@jiggai/kitchen 0.5.13 → 0.5.15

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 (169) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +2 -2
  3. package/.next/prerender-manifest.json +3 -3
  4. package/.next/server/app/_global-error.html +2 -2
  5. package/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/server/app/_not-found.html +1 -1
  12. package/.next/server/app/_not-found.rsc +2 -2
  13. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  14. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/server/app/api/agents/[id]/route.js.nft.json +1 -1
  20. package/.next/server/app/api/agents/file/route.js.nft.json +1 -1
  21. package/.next/server/app/api/agents/files/route.js.nft.json +1 -1
  22. package/.next/server/app/api/agents/skills/install/route.js.nft.json +1 -1
  23. package/.next/server/app/api/agents/skills/route.js.nft.json +1 -1
  24. package/.next/server/app/api/cron/add/route.js.nft.json +1 -1
  25. package/.next/server/app/api/cron/bulk/route.js.nft.json +1 -1
  26. package/.next/server/app/api/cron/delete/route.js.nft.json +1 -1
  27. package/.next/server/app/api/cron/edit/route.js.nft.json +1 -1
  28. package/.next/server/app/api/cron/job/route.js.nft.json +1 -1
  29. package/.next/server/app/api/cron/jobs/route.js.nft.json +1 -1
  30. package/.next/server/app/api/cron/recipe-installed/route.js.nft.json +1 -1
  31. package/.next/server/app/api/cron/worker/route.js +2 -2
  32. package/.next/server/app/api/cron/worker/route.js.nft.json +1 -1
  33. package/.next/server/app/api/goals/[id]/promote/route.js.nft.json +1 -1
  34. package/.next/server/app/api/goals/[id]/route.js.nft.json +1 -1
  35. package/.next/server/app/api/goals/route.js.nft.json +1 -1
  36. package/.next/server/app/api/recipes/[id]/route.js.nft.json +1 -1
  37. package/.next/server/app/api/recipes/clone/route.js.nft.json +1 -1
  38. package/.next/server/app/api/recipes/delete/route.js.nft.json +1 -1
  39. package/.next/server/app/api/teams/[teamId]/media-providers/route.js.nft.json +1 -1
  40. package/.next/server/app/api/teams/[teamId]/tickets/assign/route.js.nft.json +1 -1
  41. package/.next/server/app/api/teams/[teamId]/tickets/comment/route.js.nft.json +1 -1
  42. package/.next/server/app/api/teams/[teamId]/tickets/delete/route.js.nft.json +1 -1
  43. package/.next/server/app/api/teams/[teamId]/tickets/move/route.js.nft.json +1 -1
  44. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route.js.nft.json +1 -1
  45. package/.next/server/app/api/teams/file/route.js.nft.json +1 -1
  46. package/.next/server/app/api/teams/files/route.js.nft.json +1 -1
  47. package/.next/server/app/api/teams/memory/route.js.nft.json +1 -1
  48. package/.next/server/app/api/teams/meta/route.js.nft.json +1 -1
  49. package/.next/server/app/api/teams/orchestrator/route.js.nft.json +1 -1
  50. package/.next/server/app/api/teams/plugins/route.js.nft.json +1 -1
  51. package/.next/server/app/api/teams/remove-team/route.js.nft.json +1 -1
  52. package/.next/server/app/api/teams/skills/install/route.js.nft.json +1 -1
  53. package/.next/server/app/api/teams/skills/route.js.nft.json +1 -1
  54. package/.next/server/app/api/teams/workflow-runs/route.js.nft.json +1 -1
  55. package/.next/server/app/api/teams/workflow-templates/route.js.nft.json +1 -1
  56. package/.next/server/app/api/teams/workflows/route.js +2 -2
  57. package/.next/server/app/api/teams/workflows/route.js.nft.json +1 -1
  58. package/.next/server/app/api/tickets/assign/route.js.nft.json +1 -1
  59. package/.next/server/app/api/tickets/assignees/route.js.nft.json +1 -1
  60. package/.next/server/app/api/tickets/move/route.js.nft.json +1 -1
  61. package/.next/server/app/channels.html +2 -2
  62. package/.next/server/app/channels.rsc +2 -2
  63. package/.next/server/app/channels.segments/_full.segment.rsc +2 -2
  64. package/.next/server/app/channels.segments/_head.segment.rsc +1 -1
  65. package/.next/server/app/channels.segments/_index.segment.rsc +1 -1
  66. package/.next/server/app/channels.segments/_tree.segment.rsc +1 -1
  67. package/.next/server/app/channels.segments/channels/__PAGE__.segment.rsc +1 -1
  68. package/.next/server/app/channels.segments/channels.segment.rsc +1 -1
  69. package/.next/server/app/goals/new.html +2 -2
  70. package/.next/server/app/goals/new.rsc +2 -2
  71. package/.next/server/app/goals/new.segments/_full.segment.rsc +2 -2
  72. package/.next/server/app/goals/new.segments/_head.segment.rsc +1 -1
  73. package/.next/server/app/goals/new.segments/_index.segment.rsc +1 -1
  74. package/.next/server/app/goals/new.segments/_tree.segment.rsc +1 -1
  75. package/.next/server/app/goals/new.segments/goals/new/__PAGE__.segment.rsc +1 -1
  76. package/.next/server/app/goals/new.segments/goals/new.segment.rsc +1 -1
  77. package/.next/server/app/goals/new.segments/goals.segment.rsc +1 -1
  78. package/.next/server/app/goals.html +1 -1
  79. package/.next/server/app/goals.rsc +2 -2
  80. package/.next/server/app/goals.segments/_full.segment.rsc +2 -2
  81. package/.next/server/app/goals.segments/_head.segment.rsc +1 -1
  82. package/.next/server/app/goals.segments/_index.segment.rsc +1 -1
  83. package/.next/server/app/goals.segments/_tree.segment.rsc +1 -1
  84. package/.next/server/app/goals.segments/goals/__PAGE__.segment.rsc +1 -1
  85. package/.next/server/app/goals.segments/goals.segment.rsc +1 -1
  86. package/.next/server/app/page.js +1 -1
  87. package/.next/server/app/page.js.nft.json +1 -1
  88. package/.next/server/app/recipes/[id]/page.js.nft.json +1 -1
  89. package/.next/server/app/settings.html +1 -1
  90. package/.next/server/app/settings.rsc +2 -2
  91. package/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  92. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  93. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  94. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  95. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  96. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  97. package/.next/server/app/teams/[teamId]/deliverables/page.js.nft.json +1 -1
  98. package/.next/server/app/teams/[teamId]/runs/[workflowId]/[runId]/page.js +2 -2
  99. package/.next/server/app/teams/[teamId]/runs/[workflowId]/[runId]/page.js.nft.json +1 -1
  100. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page.js.nft.json +1 -1
  101. package/.next/server/app/teams/[teamId]/tickets/page.js.nft.json +1 -1
  102. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page.js +1 -1
  103. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page.js.nft.json +1 -1
  104. package/.next/server/app/teams/[teamId]/workflows/page.js.nft.json +1 -1
  105. package/.next/server/app/tickets/[ticket]/page.js.nft.json +1 -1
  106. package/.next/server/app/tickets/page.js.nft.json +1 -1
  107. package/.next/server/chunks/[root-of-the-server]__0964b35a._.js +1 -1
  108. package/.next/server/chunks/[root-of-the-server]__0964b35a._.js.map +1 -1
  109. package/.next/server/chunks/[root-of-the-server]__15008417._.js +1 -1
  110. package/.next/server/chunks/[root-of-the-server]__15008417._.js.map +1 -1
  111. package/.next/server/chunks/[root-of-the-server]__337ee852._.js +1 -1
  112. package/.next/server/chunks/[root-of-the-server]__337ee852._.js.map +1 -1
  113. package/.next/server/chunks/[root-of-the-server]__5124e458._.js +1 -1
  114. package/.next/server/chunks/[root-of-the-server]__5124e458._.js.map +1 -1
  115. package/.next/server/chunks/[root-of-the-server]__7a73dee7._.js +1 -1
  116. package/.next/server/chunks/[root-of-the-server]__7a73dee7._.js.map +1 -1
  117. package/.next/server/chunks/[root-of-the-server]__84edf1c3._.js +1 -1
  118. package/.next/server/chunks/[root-of-the-server]__84edf1c3._.js.map +1 -1
  119. package/.next/server/chunks/[root-of-the-server]__9ae5d489._.js +2 -2
  120. package/.next/server/chunks/[root-of-the-server]__9ae5d489._.js.map +1 -1
  121. package/.next/server/chunks/[root-of-the-server]__bbf9672b._.js +1 -1
  122. package/.next/server/chunks/[root-of-the-server]__bbf9672b._.js.map +1 -1
  123. package/.next/server/chunks/[root-of-the-server]__c36db8bb._.js +1 -1
  124. package/.next/server/chunks/[root-of-the-server]__c36db8bb._.js.map +1 -1
  125. package/.next/server/chunks/[root-of-the-server]__c77b0b81._.js +1 -1
  126. package/.next/server/chunks/[root-of-the-server]__c77b0b81._.js.map +1 -1
  127. package/.next/server/chunks/[root-of-the-server]__cd49b1bd._.js +1 -1
  128. package/.next/server/chunks/[root-of-the-server]__cd49b1bd._.js.map +1 -1
  129. package/.next/server/chunks/[root-of-the-server]__d8e2be0a._.js +1 -1
  130. package/.next/server/chunks/[root-of-the-server]__d8e2be0a._.js.map +1 -1
  131. package/.next/server/chunks/[root-of-the-server]__e0960142._.js +1 -1
  132. package/.next/server/chunks/[root-of-the-server]__e0960142._.js.map +1 -1
  133. package/.next/server/chunks/[root-of-the-server]__f8abf92d._.js +1 -1
  134. package/.next/server/chunks/[root-of-the-server]__f8abf92d._.js.map +1 -1
  135. package/.next/server/chunks/[root-of-the-server]__fe16f026._.js +1 -1
  136. package/.next/server/chunks/[root-of-the-server]__fe16f026._.js.map +1 -1
  137. package/.next/server/chunks/ssr/[root-of-the-server]__00365d2a._.js +1 -1
  138. package/.next/server/chunks/ssr/[root-of-the-server]__00365d2a._.js.map +1 -1
  139. package/.next/server/chunks/ssr/[root-of-the-server]__04e5789b._.js +3 -0
  140. package/.next/server/chunks/ssr/[root-of-the-server]__04e5789b._.js.map +1 -0
  141. package/.next/server/chunks/ssr/[root-of-the-server]__053078ca._.js +3 -0
  142. package/.next/server/chunks/ssr/[root-of-the-server]__053078ca._.js.map +1 -0
  143. package/.next/server/chunks/ssr/[root-of-the-server]__2b009660._.js +1 -1
  144. package/.next/server/chunks/ssr/[root-of-the-server]__2b009660._.js.map +1 -1
  145. package/.next/server/chunks/ssr/[root-of-the-server]__3b880807._.js +1 -1
  146. package/.next/server/chunks/ssr/[root-of-the-server]__3b880807._.js.map +1 -1
  147. package/.next/server/chunks/ssr/[root-of-the-server]__5180e2c4._.js +1 -1
  148. package/.next/server/chunks/ssr/[root-of-the-server]__5180e2c4._.js.map +1 -1
  149. package/.next/server/chunks/ssr/[root-of-the-server]__b16d1e60._.js +3 -0
  150. package/.next/server/chunks/ssr/[root-of-the-server]__b16d1e60._.js.map +1 -0
  151. package/.next/server/chunks/ssr/_018dfe6b._.js +1 -1
  152. package/.next/server/chunks/ssr/_018dfe6b._.js.map +1 -1
  153. package/.next/server/pages/404.html +1 -1
  154. package/.next/server/pages/500.html +2 -2
  155. package/.next/server/server-reference-manifest.js +1 -1
  156. package/.next/server/server-reference-manifest.json +1 -1
  157. package/dist/openclaw/index.mjs +367 -0
  158. package/openclaw/index.ts +32 -18
  159. package/openclaw.plugin.json +2 -2
  160. package/package.json +15 -8
  161. package/.next/server/chunks/ssr/[root-of-the-server]__03399d11._.js +0 -3
  162. package/.next/server/chunks/ssr/[root-of-the-server]__03399d11._.js.map +0 -1
  163. package/.next/server/chunks/ssr/[root-of-the-server]__076b2077._.js +0 -3
  164. package/.next/server/chunks/ssr/[root-of-the-server]__076b2077._.js.map +0 -1
  165. package/.next/server/chunks/ssr/[root-of-the-server]__997a440f._.js +0 -3
  166. package/.next/server/chunks/ssr/[root-of-the-server]__997a440f._.js.map +0 -1
  167. /package/.next/static/{IDhQCme1GnI-fdSGoYAJ3 → IT2h_v3OwuOLwfsaG6ygp}/_buildManifest.js +0 -0
  168. /package/.next/static/{IDhQCme1GnI-fdSGoYAJ3 → IT2h_v3OwuOLwfsaG6ygp}/_clientMiddlewareManifest.json +0 -0
  169. /package/.next/static/{IDhQCme1GnI-fdSGoYAJ3 → IT2h_v3OwuOLwfsaG6ygp}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><!--IDhQCme1GnI_fdSGoYAJ3--><html lang="en" data-theme="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/cc172eec0c47f311.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/8acd42df55d57556.js"/><script src="/_next/static/chunks/68a088aa49e6124a.js" async=""></script><script src="/_next/static/chunks/aebc3b6d791f68d2.js" async=""></script><script src="/_next/static/chunks/8aac543d98940eb3.js" async=""></script><script src="/_next/static/chunks/turbopack-bdd9478663f034d6.js" async=""></script><script src="/_next/static/chunks/f7f157ba542e1ae5.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/0bd6498bda341889.js" async=""></script><script src="/_next/static/chunks/9c627cb11f73ac4c.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>ClawKitchen (0.5.13-beta)</title><meta name="description" content="Local-first UI for authoring ClawRecipes recipes and scaffolding agents/teams."/><link rel="manifest" href="/manifest.webmanifest"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/favicon-16x16.png" sizes="16x16" type="image/png"/><link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-dvh w-dvw overflow-hidden"><aside class="flex shrink-0 flex-col border-r border-[color:var(--ck-border-subtle)] bg-[color:var(--ck-bg-soft)]/95 backdrop-blur-[var(--ck-glass-blur)] w-62"><div class="flex h-14 items-center border-b border-[color:var(--ck-border-subtle)] justify-between gap-2 px-3"><a class="text-sm font-semibold tracking-tight" title="Home" href="/">Claw Kitchen</a><button class="grid h-9 w-9 place-items-center rounded-lg text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/10 hover:text-[color:var(--ck-text-primary)]" title="Collapse sidebar"><svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="3"></rect><path d="M9 3v18"></path><path d="M14 14l-2-2 2-2"></path></svg></button></div><div class="border-b border-[color:var(--ck-border-subtle)] p-2"><div class="flex flex-col gap-1"><div class="px-2 pt-1 text-xs font-semibold uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">Team</div><select class="w-full rounded-lg border border-white/10 bg-white/5 px-2 py-2 text-sm text-[color:var(--ck-text-primary)]"><option value="" selected="">All teams</option></select></div></div><nav class="min-h-0 flex-1 overflow-auto p-2"><div class="mt-2 px-2 pb-2 pt-2"></div><a title="Agents" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 11l9-8 9 8"></path><path d="M5 10v10h14V10"></path></svg></span></span><span>Agents</span></a><a title="Recipes" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/recipes"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 4h12v16H6z"></path><path d="M9 8h6"></path><path d="M9 12h6"></path></svg></span></span><span>Recipes</span></a><a title="Tickets" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/tickets"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16v4a2 2 0 0 1 0 4v4H4v-4a2 2 0 0 0 0-4z"></path></svg></span></span><span>Tickets</span></a><a title="Channels" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/channels"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16"></path><path d="M4 12h16"></path><path d="M4 18h16"></path><path d="M7 9h0"></path></svg></span></span><span>Channels</span></a><a title="Goals" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/goals"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 3"></path></svg></span></span><span>Goals</span></a><a title="Cron jobs" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/cron-jobs"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5"></path></svg></span></span><span>Cron jobs</span></a><a title="Runs" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/runs"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19h16"></path><path d="M6 16l4-4 3 3 5-7"></path><circle cx="10" cy="12" r="1"></circle><circle cx="13" cy="15" r="1"></circle><circle cx="18" cy="8" r="1"></circle></svg></span></span><span>Runs</span></a><a title="Settings" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/settings"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z"></path><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"></path></svg></span></span><span>Settings</span></a></nav><div class="flex items-center justify-between gap-2 border-t border-[color:var(--ck-border-subtle)] p-2"><a href="https://docs.clawkitchen.ai" target="_blank" rel="noreferrer" class="rounded-lg 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)]" title="Docs">Docs</a></div></aside><div class="min-w-0 flex-1"><main class="h-full overflow-auto px-6 py-5 lg:px-10"><div class="mx-auto max-w-2xl px-6 py-12"><h1 class="text-xl font-semibold">Page not found</h1><p class="mt-2 text-sm text-[color:var(--ck-text-secondary)]">The page you requested does not exist.</p></div><!--$--><!--/$--></main></div></div><div aria-live="assertive" class="pointer-events-none fixed inset-0 z-[100] flex items-end px-4 py-6 sm:p-6"><div class="flex w-full flex-col items-start space-y-4"></div></div><script src="/_next/static/chunks/8acd42df55d57556.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[49830,[\"/_next/static/chunks/f7f157ba542e1ae5.js\"],\"AppShell\"]\n3:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n5:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n6:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nc:I[63491,[\"/_next/static/chunks/9c627cb11f73ac4c.js\"],\"default\"]\n:HL[\"/_next/static/chunks/cc172eec0c47f311.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"IDhQCme1GnI-fdSGoYAJ3\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/cc172eec0c47f311.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/f7f157ba542e1ae5.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{}],[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-2xl px-6 py-12\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"text-xl font-semibold\",\"children\":\"Page not found\"}],[\"$\",\"p\",null,{\"className\":\"mt-2 text-sm text-[color:var(--ck-text-secondary)]\",\"children\":\"The page you requested does not exist.\"}]]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-2xl px-6 py-12\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"text-xl font-semibold\",\"children\":\"Page not found\"}],[\"$\",\"p\",null,{\"className\":\"mt-2 text-sm text-[color:var(--ck-text-secondary)]\",\"children\":\"The page you requested does not exist.\"}]]}],null,[\"$\",\"$L5\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@7\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"d:I[27201,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"IconMark\"]\n7:null\nb:[[\"$\",\"title\",\"0\",{\"children\":\"ClawKitchen (0.5.13-beta)\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Local-first UI for authoring ClawRecipes recipes and scaffolding agents/teams.\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/favicon-16x16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon-32x32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"7\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$Ld\",\"8\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--IT2h_v3OwuOLwfsaG6ygp--><html lang="en" data-theme="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/cc172eec0c47f311.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/8acd42df55d57556.js"/><script src="/_next/static/chunks/68a088aa49e6124a.js" async=""></script><script src="/_next/static/chunks/aebc3b6d791f68d2.js" async=""></script><script src="/_next/static/chunks/8aac543d98940eb3.js" async=""></script><script src="/_next/static/chunks/turbopack-bdd9478663f034d6.js" async=""></script><script src="/_next/static/chunks/f7f157ba542e1ae5.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/0bd6498bda341889.js" async=""></script><script src="/_next/static/chunks/9c627cb11f73ac4c.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>ClawKitchen (0.5.15-beta)</title><meta name="description" content="Local-first UI for authoring ClawRecipes recipes and scaffolding agents/teams."/><link rel="manifest" href="/manifest.webmanifest"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/favicon-16x16.png" sizes="16x16" type="image/png"/><link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-dvh w-dvw overflow-hidden"><aside class="flex shrink-0 flex-col border-r border-[color:var(--ck-border-subtle)] bg-[color:var(--ck-bg-soft)]/95 backdrop-blur-[var(--ck-glass-blur)] w-62"><div class="flex h-14 items-center border-b border-[color:var(--ck-border-subtle)] justify-between gap-2 px-3"><a class="text-sm font-semibold tracking-tight" title="Home" href="/">Claw Kitchen</a><button class="grid h-9 w-9 place-items-center rounded-lg text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/10 hover:text-[color:var(--ck-text-primary)]" title="Collapse sidebar"><svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="3"></rect><path d="M9 3v18"></path><path d="M14 14l-2-2 2-2"></path></svg></button></div><div class="border-b border-[color:var(--ck-border-subtle)] p-2"><div class="flex flex-col gap-1"><div class="px-2 pt-1 text-xs font-semibold uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">Team</div><select class="w-full rounded-lg border border-white/10 bg-white/5 px-2 py-2 text-sm text-[color:var(--ck-text-primary)]"><option value="" selected="">All teams</option></select></div></div><nav class="min-h-0 flex-1 overflow-auto p-2"><div class="mt-2 px-2 pb-2 pt-2"></div><a title="Agents" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 11l9-8 9 8"></path><path d="M5 10v10h14V10"></path></svg></span></span><span>Agents</span></a><a title="Recipes" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/recipes"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 4h12v16H6z"></path><path d="M9 8h6"></path><path d="M9 12h6"></path></svg></span></span><span>Recipes</span></a><a title="Tickets" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/tickets"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h16v4a2 2 0 0 1 0 4v4H4v-4a2 2 0 0 0 0-4z"></path></svg></span></span><span>Tickets</span></a><a title="Channels" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/channels"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16"></path><path d="M4 12h16"></path><path d="M4 18h16"></path><path d="M7 9h0"></path></svg></span></span><span>Channels</span></a><a title="Goals" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/goals"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 3"></path></svg></span></span><span>Goals</span></a><a title="Cron jobs" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/cron-jobs"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5"></path></svg></span></span><span>Cron jobs</span></a><a title="Runs" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/runs"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19h16"></path><path d="M6 16l4-4 3 3 5-7"></path><circle cx="10" cy="12" r="1"></circle><circle cx="13" cy="15" r="1"></circle><circle cx="18" cy="8" r="1"></circle></svg></span></span><span>Runs</span></a><a title="Settings" class="flex items-center rounded-lg text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)] gap-4 px-4 py-3" href="/settings"><span aria-hidden="true"><span class="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]" aria-hidden="true"><svg viewBox="0 0 24 24" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z"></path><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"></path></svg></span></span><span>Settings</span></a></nav><div class="flex items-center justify-between gap-2 border-t border-[color:var(--ck-border-subtle)] p-2"><a href="https://docs.clawkitchen.ai" target="_blank" rel="noreferrer" class="rounded-lg 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)]" title="Docs">Docs</a></div></aside><div class="min-w-0 flex-1"><main class="h-full overflow-auto px-6 py-5 lg:px-10"><div class="mx-auto max-w-2xl px-6 py-12"><h1 class="text-xl font-semibold">Page not found</h1><p class="mt-2 text-sm text-[color:var(--ck-text-secondary)]">The page you requested does not exist.</p></div><!--$--><!--/$--></main></div></div><div aria-live="assertive" class="pointer-events-none fixed inset-0 z-[100] flex items-end px-4 py-6 sm:p-6"><div class="flex w-full flex-col items-start space-y-4"></div></div><script src="/_next/static/chunks/8acd42df55d57556.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[49830,[\"/_next/static/chunks/f7f157ba542e1ae5.js\"],\"AppShell\"]\n3:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n5:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n6:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nc:I[63491,[\"/_next/static/chunks/9c627cb11f73ac4c.js\"],\"default\"]\n:HL[\"/_next/static/chunks/cc172eec0c47f311.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"IT2h_v3OwuOLwfsaG6ygp\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/cc172eec0c47f311.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/f7f157ba542e1ae5.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"dark\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{}],[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"className\":\"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-2xl px-6 py-12\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"text-xl font-semibold\",\"children\":\"Page not found\"}],[\"$\",\"p\",null,{\"className\":\"mt-2 text-sm text-[color:var(--ck-text-secondary)]\",\"children\":\"The page you requested does not exist.\"}]]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-2xl px-6 py-12\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"text-xl font-semibold\",\"children\":\"Page not found\"}],[\"$\",\"p\",null,{\"className\":\"mt-2 text-sm text-[color:var(--ck-text-secondary)]\",\"children\":\"The page you requested does not exist.\"}]]}],null,[\"$\",\"$L5\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@7\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$6\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"d:I[27201,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"IconMark\"]\n7:null\nb:[[\"$\",\"title\",\"0\",{\"children\":\"ClawKitchen (0.5.15-beta)\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Local-first UI for authoring ClawRecipes recipes and scaffolding agents/teams.\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/favicon-16x16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon-32x32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"7\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$Ld\",\"8\",{}]]\n"])</script></body></html>
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--IDhQCme1GnI_fdSGoYAJ3--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/8acd42df55d57556.js"/><script src="/_next/static/chunks/68a088aa49e6124a.js" async=""></script><script src="/_next/static/chunks/aebc3b6d791f68d2.js" async=""></script><script src="/_next/static/chunks/8aac543d98940eb3.js" async=""></script><script src="/_next/static/chunks/turbopack-bdd9478663f034d6.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/0bd6498bda341889.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><link rel="manifest" href="/manifest.webmanifest"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/8acd42df55d57556.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"IDhQCme1GnI-fdSGoYAJ3\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:I[27201,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"IconMark\"]\n6:null\na:[[\"$\",\"link\",\"0\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lc\",\"2\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--IT2h_v3OwuOLwfsaG6ygp--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/8acd42df55d57556.js"/><script src="/_next/static/chunks/68a088aa49e6124a.js" async=""></script><script src="/_next/static/chunks/aebc3b6d791f68d2.js" async=""></script><script src="/_next/static/chunks/8aac543d98940eb3.js" async=""></script><script src="/_next/static/chunks/turbopack-bdd9478663f034d6.js" async=""></script><script src="/_next/static/chunks/ff1a16fafef87110.js" async=""></script><script src="/_next/static/chunks/0bd6498bda341889.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><link rel="manifest" href="/manifest.webmanifest"/><link rel="icon" href="/favicon.ico?favicon.0b3bf435.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/8acd42df55d57556.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"ViewportBoundary\"]\n9:I[97367,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"MetadataBoundary\"]\nb:I[68027,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"IT2h_v3OwuOLwfsaG6ygp\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:I[27201,[\"/_next/static/chunks/ff1a16fafef87110.js\",\"/_next/static/chunks/0bd6498bda341889.js\"],\"IconMark\"]\n6:null\na:[[\"$\",\"link\",\"0\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0b3bf435.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lc\",\"2\",{}]]\n"])</script></body></html>
@@ -1 +1 @@
1
- self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"FOa5Ox04kXyHML7JhwP7oCDIu8nEyexqbLVNi5x2vpc=\"\n}"
1
+ self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"5xnyY9KyKFhaADavBTjqAo6NiD58qzi3YGkxKA3Bj5Y=\"\n}"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "node": {},
3
3
  "edge": {},
4
- "encryptionKey": "FOa5Ox04kXyHML7JhwP7oCDIu8nEyexqbLVNi5x2vpc="
4
+ "encryptionKey": "5xnyY9KyKFhaADavBTjqAo6NiD58qzi3YGkxKA3Bj5Y="
5
5
  }
@@ -0,0 +1,367 @@
1
+ // openclaw/index.ts
2
+ import http from "node:http";
3
+ import path2 from "node:path";
4
+ import fs2 from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import { homedir } from "node:os";
7
+ import next from "next";
8
+
9
+ // openclaw/list-installed-plugins.ts
10
+ import fs from "node:fs";
11
+ import path from "node:path";
12
+ function listInstalledPlugins(pluginsDir) {
13
+ const nmDir = path.join(pluginsDir, "node_modules");
14
+ if (!fs.existsSync(nmDir)) return [];
15
+ const found = [];
16
+ const entries = fs.readdirSync(nmDir);
17
+ for (const entry of entries) {
18
+ const dirs = entry.startsWith("@") ? fs.readdirSync(path.join(nmDir, entry)).map((s) => path.join(nmDir, entry, s)) : [path.join(nmDir, entry)];
19
+ for (const d of dirs) {
20
+ try {
21
+ const raw = JSON.parse(fs.readFileSync(path.join(d, "package.json"), "utf8"));
22
+ if (raw.kitchenPlugin?.id) {
23
+ found.push({
24
+ id: raw.kitchenPlugin.id,
25
+ name: raw.kitchenPlugin.name || raw.name || "",
26
+ version: raw.version || "0.0.0",
27
+ teamTypes: raw.kitchenPlugin.teamTypes || []
28
+ });
29
+ }
30
+ } catch {
31
+ }
32
+ }
33
+ }
34
+ return found;
35
+ }
36
+
37
+ // openclaw/index.ts
38
+ function parseAuthMode(v) {
39
+ const s = String(v ?? "").trim().toLowerCase();
40
+ if (s === "off") return "off";
41
+ if (s === "local") return "local";
42
+ return "on";
43
+ }
44
+ function isLocalhost(host) {
45
+ const h = (host || "").trim().toLowerCase();
46
+ return h === "127.0.0.1" || h === "localhost" || h === "::1";
47
+ }
48
+ function isLoopbackRemoteAddress(addr) {
49
+ const a = String(addr || "").trim().toLowerCase();
50
+ if (!a) return false;
51
+ if (a === "::1") return true;
52
+ if (a.startsWith("::ffff:")) {
53
+ const v4 = a.slice("::ffff:".length);
54
+ return v4 === "127.0.0.1";
55
+ }
56
+ return a === "127.0.0.1";
57
+ }
58
+ function parseBasicAuth(req) {
59
+ const header = String(req.headers.authorization || "").trim();
60
+ if (!header.toLowerCase().startsWith("basic ")) return null;
61
+ try {
62
+ const raw = Buffer.from(header.slice(6), "base64").toString("utf8");
63
+ const idx = raw.indexOf(":");
64
+ if (idx === -1) return null;
65
+ return { user: raw.slice(0, idx), pass: raw.slice(idx + 1) };
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
70
+ function parseCookies(req) {
71
+ const header = String(req.headers.cookie || "");
72
+ const out = {};
73
+ for (const part of header.split(";")) {
74
+ const [kRaw, ...vParts] = part.trim().split("=");
75
+ if (!kRaw) continue;
76
+ const k = kRaw.trim();
77
+ const v = vParts.join("=").trim();
78
+ if (!k) continue;
79
+ out[k] = decodeURIComponent(v || "");
80
+ }
81
+ return out;
82
+ }
83
+ var server = null;
84
+ var startedAt = null;
85
+ function resolveKitchenRoot() {
86
+ const moduleDir = path2.dirname(fileURLToPath(import.meta.url));
87
+ const candidates = [moduleDir, path2.resolve(moduleDir, ".."), path2.resolve(moduleDir, "../..")];
88
+ for (const candidate of candidates) {
89
+ const packageJsonPath = path2.join(candidate, "package.json");
90
+ if (!fs2.existsSync(packageJsonPath)) continue;
91
+ try {
92
+ const pkg = JSON.parse(fs2.readFileSync(packageJsonPath, "utf8"));
93
+ if (pkg?.name === "@jiggai/kitchen") return candidate;
94
+ } catch {
95
+ }
96
+ }
97
+ return path2.resolve(moduleDir, "..");
98
+ }
99
+ async function startKitchen(api, cfg) {
100
+ if (server) return;
101
+ const host = String(cfg.host || "127.0.0.1").trim();
102
+ const port = Number(cfg.port || 7777);
103
+ const dev = cfg.dev === true;
104
+ const authToken = String(cfg.authToken ?? "");
105
+ const qaToken = String(cfg.qaToken ?? "");
106
+ const authMode = parseAuthMode(cfg.authMode);
107
+ if (authMode !== "off" && !isLocalhost(host) && !authToken.trim()) {
108
+ throw new Error(
109
+ "Kitchen: authToken is required when binding to a non-localhost host (for Tailscale/remote access)."
110
+ );
111
+ }
112
+ const rootDir = resolveKitchenRoot();
113
+ const sqliteBindingPath = path2.join(rootDir, "node_modules", "better-sqlite3", "build", "Release", "better_sqlite3.node");
114
+ if (!fs2.existsSync(sqliteBindingPath)) {
115
+ api.logger.info("[kitchen] better-sqlite3 native binary missing \u2014 rebuilding for this platform...");
116
+ const res = await api.runtime.system.runCommandWithTimeout(
117
+ ["npm", "rebuild", "better-sqlite3"],
118
+ { timeoutMs: 12e4, cwd: rootDir }
119
+ );
120
+ if (res.code !== 0) {
121
+ api.logger.error(`[kitchen] failed to rebuild better-sqlite3: ${res.stderr || res.stdout}`);
122
+ } else {
123
+ api.logger.info("[kitchen] better-sqlite3 rebuilt successfully.");
124
+ }
125
+ }
126
+ const app = next({ dev, dir: rootDir });
127
+ await app.prepare();
128
+ const handle = app.getRequestHandler();
129
+ server = http.createServer(async (req, res) => {
130
+ try {
131
+ const url = req.url || "/";
132
+ if (url.startsWith("/healthz")) {
133
+ res.statusCode = 200;
134
+ res.setHeader("content-type", "application/json");
135
+ res.end(JSON.stringify({ ok: true, startedAt }));
136
+ return;
137
+ }
138
+ const shouldProtect = authMode !== "off" && !isLocalhost(host) && authToken.trim();
139
+ const isLocalRequest = isLoopbackRemoteAddress(req.socket.remoteAddress);
140
+ const pathname = new URL(url, `http://${host}:${port}`).pathname;
141
+ if (pathname === "/manifest.webmanifest") {
142
+ await handle(req, res);
143
+ return;
144
+ }
145
+ if (shouldProtect && !(authMode === "local" && isLocalRequest)) {
146
+ const cookies = parseCookies(req);
147
+ const hasQaCookie = qaToken.trim() && cookies.kitchenQaToken === qaToken;
148
+ const reqUrl = new URL(url, `http://${host}:${port}`);
149
+ const qpQaToken = String(reqUrl.searchParams.get("qaToken") || "");
150
+ if (!hasQaCookie && qaToken.trim() && qpQaToken && qpQaToken === qaToken) {
151
+ res.statusCode = 302;
152
+ res.setHeader(
153
+ "set-cookie",
154
+ `kitchenQaToken=${encodeURIComponent(qaToken)}; HttpOnly; Path=/; Max-Age=${15 * 60}; SameSite=Lax`
155
+ );
156
+ reqUrl.searchParams.delete("qaToken");
157
+ res.setHeader("location", reqUrl.pathname + (reqUrl.search ? `?${reqUrl.searchParams.toString()}` : ""));
158
+ api.logger.warn(`[kitchen] QA token used for ${req.method || "GET"} ${reqUrl.pathname}`);
159
+ res.end("OK");
160
+ return;
161
+ }
162
+ const creds = parseBasicAuth(req);
163
+ const ok = hasQaCookie || creds && creds.user === "kitchen" && creds.pass === authToken;
164
+ if (!ok) {
165
+ res.statusCode = 401;
166
+ res.setHeader("www-authenticate", 'Basic realm="kitchen"');
167
+ res.end("Unauthorized");
168
+ return;
169
+ }
170
+ }
171
+ await handle(req, res);
172
+ } catch (e) {
173
+ api.logger.error(`[kitchen] request error: ${e instanceof Error ? e.message : String(e)}`);
174
+ res.statusCode = 500;
175
+ res.end("Internal Server Error");
176
+ }
177
+ });
178
+ await new Promise((resolve, reject) => {
179
+ server.once("error", reject);
180
+ server.listen(port, host, () => resolve());
181
+ });
182
+ startedAt = (/* @__PURE__ */ new Date()).toISOString();
183
+ api.logger.info(`[kitchen] listening on http://${host}:${port} (dev=${dev})`);
184
+ }
185
+ async function stopKitchen(api) {
186
+ if (!server) return;
187
+ const s = server;
188
+ server = null;
189
+ startedAt = null;
190
+ await new Promise((resolve) => s.close(() => resolve()));
191
+ api.logger.info("[kitchen] stopped");
192
+ }
193
+ var kitchenPlugin = {
194
+ id: "kitchen",
195
+ name: "ClawKitchen",
196
+ description: "Local UI for managing recipes, teams, agents, cron jobs, and skills.",
197
+ configSchema: {
198
+ type: "object",
199
+ additionalProperties: false,
200
+ properties: {
201
+ enabled: { type: "boolean", default: true },
202
+ dev: {
203
+ type: "boolean",
204
+ default: false,
205
+ description: "Run Next.js in dev mode (not recommended for end users)."
206
+ },
207
+ host: { type: "string", default: "127.0.0.1" },
208
+ port: { type: "integer", default: 7777, minimum: 1, maximum: 65535 },
209
+ authMode: {
210
+ type: "string",
211
+ enum: ["on", "local", "off"],
212
+ default: "on",
213
+ description: "Auth protection mode (on|local|off)."
214
+ },
215
+ authToken: {
216
+ type: "string",
217
+ default: "",
218
+ description: "Required when host is not localhost. Used for HTTP Basic auth (username: kitchen)."
219
+ },
220
+ qaToken: {
221
+ type: "string",
222
+ default: "",
223
+ description: "Optional QA-only bypass token. If set, visiting any URL with ?qaToken=<token> sets a short-lived cookie for headless/automated access."
224
+ }
225
+ }
226
+ },
227
+ register(api) {
228
+ globalThis.__clawkitchen_api = api;
229
+ const cfg = api.pluginConfig || {};
230
+ api.registerCli(
231
+ ({ program }) => {
232
+ const cmd = program.command("kitchen").description("ClawKitchen UI");
233
+ const pluginsDir = path2.join(homedir(), ".openclaw", "kitchen", "plugins");
234
+ cmd.command("status").description("Print Kitchen status").action(async () => {
235
+ const host = String(cfg.host || "127.0.0.1").trim();
236
+ const port = Number(cfg.port || 7777);
237
+ const url = `http://${host}:${port}`;
238
+ const result = { ok: true, running: false, url, startedAt: null };
239
+ try {
240
+ const controller = new AbortController();
241
+ const timer = setTimeout(() => controller.abort(), 3e3);
242
+ const resp = await fetch(`http://127.0.0.1:${port}/healthz`, {
243
+ signal: controller.signal
244
+ });
245
+ clearTimeout(timer);
246
+ if (resp.ok) {
247
+ const data = await resp.json();
248
+ result.running = true;
249
+ result.startedAt = data.startedAt || null;
250
+ }
251
+ } catch {
252
+ result.running = false;
253
+ }
254
+ result.plugins = listInstalledPlugins(pluginsDir);
255
+ console.log(JSON.stringify(result, null, 2));
256
+ });
257
+ cmd.command("restart").description("Restart Kitchen (clears plugin cache)").action(async () => {
258
+ const port = Number(cfg.port || 7777);
259
+ if (server) {
260
+ console.log("Restarting Kitchen (in-process)...");
261
+ await stopKitchen(api);
262
+ await startKitchen(api, cfg);
263
+ console.log("\u2705 Kitchen restarted.");
264
+ return;
265
+ }
266
+ let running = false;
267
+ try {
268
+ const controller = new AbortController();
269
+ const timer = setTimeout(() => controller.abort(), 3e3);
270
+ const resp = await fetch(`http://127.0.0.1:${port}/healthz`, {
271
+ signal: controller.signal
272
+ });
273
+ clearTimeout(timer);
274
+ running = resp.ok;
275
+ } catch {
276
+ }
277
+ if (!running) {
278
+ console.log("Kitchen is not running. Start the gateway to launch Kitchen.");
279
+ return;
280
+ }
281
+ console.log("Kitchen is running inside the gateway process.");
282
+ console.log("To restart, run: openclaw gateway restart");
283
+ });
284
+ cmd.command("open").description("Print the Kitchen URL").action(() => {
285
+ const host = String(cfg.host || "127.0.0.1").trim();
286
+ const port = Number(cfg.port || 7777);
287
+ console.log(`http://${host}:${port}`);
288
+ });
289
+ const pluginsCmd = cmd.command("plugins").description("Manage Kitchen plugins");
290
+ pluginsCmd.command("list").description("List installed Kitchen plugins").action(() => {
291
+ const found = listInstalledPlugins(pluginsDir);
292
+ if (!found.length) {
293
+ console.log("No Kitchen plugins installed.");
294
+ return;
295
+ }
296
+ console.log(JSON.stringify(found, null, 2));
297
+ });
298
+ pluginsCmd.command("install <package>").description("Install a Kitchen plugin from npm (e.g. @jiggai/kitchen-plugin-marketing)").action(async (pkg) => {
299
+ fs2.mkdirSync(pluginsDir, { recursive: true });
300
+ const pjPath = path2.join(pluginsDir, "package.json");
301
+ if (!fs2.existsSync(pjPath)) {
302
+ fs2.writeFileSync(pjPath, JSON.stringify({ name: "kitchen-plugins", version: "1.0.0", private: true, dependencies: {} }, null, 2));
303
+ }
304
+ console.log(`Installing ${pkg}...`);
305
+ try {
306
+ const res = await api.runtime.system.runCommandWithTimeout(
307
+ ["npm", "install", "--save", pkg],
308
+ { timeoutMs: 12e4, cwd: pluginsDir }
309
+ );
310
+ if (res.code !== 0) throw new Error(res.stderr || res.stdout || "npm install failed");
311
+ if (res.stdout) console.log(res.stdout);
312
+ console.log(`
313
+ \u2705 Plugin ${pkg} installed. Restart the gateway to activate.`);
314
+ } catch (e) {
315
+ console.error(`
316
+ \u274C Failed to install ${pkg}. Check the package name and try again.`);
317
+ if (e instanceof Error && e.message) console.error(e.message);
318
+ process.exit(1);
319
+ }
320
+ });
321
+ pluginsCmd.command("remove <package>").description("Remove a Kitchen plugin").action(async (pkg) => {
322
+ const pjPath = path2.join(pluginsDir, "package.json");
323
+ if (!fs2.existsSync(pjPath)) {
324
+ console.error("No plugins installed.");
325
+ process.exit(1);
326
+ }
327
+ console.log(`Removing ${pkg}...`);
328
+ try {
329
+ const res = await api.runtime.system.runCommandWithTimeout(
330
+ ["npm", "uninstall", pkg],
331
+ { timeoutMs: 6e4, cwd: pluginsDir }
332
+ );
333
+ if (res.code !== 0) throw new Error(res.stderr || res.stdout || "npm uninstall failed");
334
+ if (res.stdout) console.log(res.stdout);
335
+ console.log(`
336
+ \u2705 Plugin ${pkg} removed. Restart the gateway to apply.`);
337
+ } catch (e) {
338
+ console.error(`
339
+ \u274C Failed to remove ${pkg}.`);
340
+ if (e instanceof Error && e.message) console.error(e.message);
341
+ process.exit(1);
342
+ }
343
+ });
344
+ },
345
+ { commands: ["kitchen"] }
346
+ );
347
+ api.on("gateway_start", async () => {
348
+ if (cfg.enabled === false) return;
349
+ try {
350
+ await startKitchen(api, cfg);
351
+ } catch (e) {
352
+ api.logger.error(`[kitchen] failed to start: ${e instanceof Error ? e.message : String(e)}`);
353
+ }
354
+ });
355
+ api.on("gateway_stop", async () => {
356
+ try {
357
+ await stopKitchen(api);
358
+ } catch (e) {
359
+ api.logger.error(`[kitchen] failed to stop: ${e instanceof Error ? e.message : String(e)}`);
360
+ }
361
+ });
362
+ }
363
+ };
364
+ var index_default = kitchenPlugin;
365
+ export {
366
+ index_default as default
367
+ };
package/openclaw/index.ts CHANGED
@@ -90,6 +90,22 @@ function parseCookies(req: http.IncomingMessage): Record<string, string> {
90
90
  let server: http.Server | null = null;
91
91
  let startedAt: string | null = null;
92
92
 
93
+ function resolveKitchenRoot() {
94
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
95
+ const candidates = [moduleDir, path.resolve(moduleDir, ".."), path.resolve(moduleDir, "../..")];
96
+ for (const candidate of candidates) {
97
+ const packageJsonPath = path.join(candidate, "package.json");
98
+ if (!fs.existsSync(packageJsonPath)) continue;
99
+ try {
100
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
101
+ if (pkg?.name === "@jiggai/kitchen") return candidate;
102
+ } catch {
103
+ // Keep looking; a malformed package.json should not hide a valid root candidate.
104
+ }
105
+ }
106
+ return path.resolve(moduleDir, "..");
107
+ }
108
+
93
109
  async function startKitchen(api: OpenClawPluginApi, cfg: KitchenConfig) {
94
110
  if (server) return;
95
111
 
@@ -108,7 +124,7 @@ async function startKitchen(api: OpenClawPluginApi, cfg: KitchenConfig) {
108
124
  );
109
125
  }
110
126
 
111
- const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
127
+ const rootDir = resolveKitchenRoot();
112
128
 
113
129
  // Ensure better-sqlite3 native binary is compiled for this platform.
114
130
  // openclaw installs plugins with --ignore-scripts, so node-gyp never runs.
@@ -427,23 +443,21 @@ const kitchenPlugin = {
427
443
  { commands: ["kitchen"] },
428
444
  );
429
445
 
430
- api.registerService({
431
- id: "kitchen",
432
- start: async () => {
433
- if (cfg.enabled === false) return;
434
- try {
435
- await startKitchen(api, cfg);
436
- } catch (e: unknown) {
437
- api.logger.error(`[kitchen] failed to start: ${e instanceof Error ? e.message : String(e)}`);
438
- }
439
- },
440
- stop: async () => {
441
- try {
442
- await stopKitchen(api);
443
- } catch (e: unknown) {
444
- api.logger.error(`[kitchen] failed to stop: ${e instanceof Error ? e.message : String(e)}`);
445
- }
446
- },
446
+ api.on("gateway_start", async () => {
447
+ if (cfg.enabled === false) return;
448
+ try {
449
+ await startKitchen(api, cfg);
450
+ } catch (e: unknown) {
451
+ api.logger.error(`[kitchen] failed to start: ${e instanceof Error ? e.message : String(e)}`);
452
+ }
453
+ });
454
+
455
+ api.on("gateway_stop", async () => {
456
+ try {
457
+ await stopKitchen(api);
458
+ } catch (e: unknown) {
459
+ api.logger.error(`[kitchen] failed to stop: ${e instanceof Error ? e.message : String(e)}`);
460
+ }
447
461
  });
448
462
  },
449
463
  };
@@ -2,7 +2,7 @@
2
2
  "id": "kitchen",
3
3
  "name": "ClawKitchen",
4
4
  "description": "Local UI for managing OpenClaw recipes, teams, agents, cron jobs, and skills.",
5
- "version": "0.5.13",
5
+ "version": "0.5.15",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
@@ -74,5 +74,5 @@
74
74
  "help": "on: require Basic auth; local: allow localhost unauthenticated; off: disable auth (not recommended)."
75
75
  }
76
76
  },
77
- "main": "openclaw/index.ts"
77
+ "main": "dist/openclaw/index.mjs"
78
78
  }