@jiggai/kitchen 0.1.3 → 0.1.7
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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +0 -24
- package/.next/server/app/_global-error/page.js +1 -1
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +2 -2
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/agents/[agentId]/page.js +1 -1
- package/.next/server/app/agents/[agentId]/page.js.nft.json +1 -1
- package/.next/server/app/agents/[agentId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/[id]/route.js +1 -1
- package/.next/server/app/api/agents/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/add/route.js +1 -1
- package/.next/server/app/api/agents/add/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/file/route.js +1 -1
- package/.next/server/app/api/agents/file/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/files/route.js +1 -1
- package/.next/server/app/api/agents/files/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/identity/route.js +1 -1
- package/.next/server/app/api/agents/identity/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/route.js +1 -1
- package/.next/server/app/api/agents/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/skills/install/route.js +1 -1
- package/.next/server/app/api/agents/skills/install/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/skills/route.js +1 -1
- package/.next/server/app/api/agents/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/update/route.js +1 -1
- package/.next/server/app/api/agents/update/route.js.nft.json +1 -1
- package/.next/server/app/api/channels/bindings/route.js +1 -1
- package/.next/server/app/api/channels/bindings/route.js.nft.json +1 -1
- package/.next/server/app/api/cron/delete/route.js +1 -1
- package/.next/server/app/api/cron/delete/route.js.nft.json +1 -1
- package/.next/server/app/api/cron/job/route.js +1 -1
- package/.next/server/app/api/cron/job/route.js.nft.json +1 -1
- package/.next/server/app/api/cron/jobs/route.js +1 -1
- package/.next/server/app/api/cron/jobs/route.js.nft.json +1 -1
- package/.next/server/app/api/cron/recipe-installed/route.js +1 -1
- package/.next/server/app/api/cron/recipe-installed/route.js.nft.json +1 -1
- package/.next/server/app/api/gateway/restart/route.js +1 -1
- package/.next/server/app/api/gateway/restart/route.js.nft.json +1 -1
- package/.next/server/app/api/goals/[id]/promote/route.js +1 -1
- package/.next/server/app/api/goals/[id]/promote/route.js.nft.json +1 -1
- package/.next/server/app/api/goals/[id]/route.js +1 -1
- package/.next/server/app/api/goals/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/goals/route.js +1 -1
- package/.next/server/app/api/goals/route.js.nft.json +1 -1
- package/.next/server/app/api/ids/check/route.js +1 -1
- package/.next/server/app/api/ids/check/route.js.nft.json +1 -1
- package/.next/server/app/api/marketplace/recipes/[slug]/route.js +1 -1
- package/.next/server/app/api/marketplace/recipes/[slug]/route.js.nft.json +1 -1
- package/.next/server/app/api/marketplace/recipes/route.js +1 -1
- package/.next/server/app/api/marketplace/recipes/route.js.nft.json +1 -1
- package/.next/server/app/api/recipes/[id]/route.js +1 -1
- package/.next/server/app/api/recipes/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/recipes/clone/route.js +1 -1
- package/.next/server/app/api/recipes/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/recipes/delete/route.js +1 -1
- package/.next/server/app/api/recipes/delete/route.js.nft.json +1 -1
- package/.next/server/app/api/recipes/route.js +1 -1
- package/.next/server/app/api/recipes/route.js.nft.json +1 -1
- package/.next/server/app/api/recipes/team-agents/route.js +1 -1
- package/.next/server/app/api/recipes/team-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/scaffold/route.js +2 -2
- package/.next/server/app/api/scaffold/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/cron-installation/route.js +1 -1
- package/.next/server/app/api/settings/cron-installation/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/available/route.js +1 -1
- package/.next/server/app/api/skills/available/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/file/route.js +1 -1
- package/.next/server/app/api/teams/file/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/files/route.js +1 -1
- package/.next/server/app/api/teams/files/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/meta/route.js +1 -1
- package/.next/server/app/api/teams/meta/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/remove-team/route.js +1 -1
- package/.next/server/app/api/teams/remove-team/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/skills/install/route.js +1 -1
- package/.next/server/app/api/teams/skills/install/route.js.nft.json +1 -1
- package/.next/server/app/api/teams/skills/route.js +1 -1
- package/.next/server/app/api/teams/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/tickets/move/route.js +1 -1
- package/.next/server/app/api/tickets/move/route.js.nft.json +1 -1
- package/.next/server/app/channels/page.js +1 -1
- package/.next/server/app/channels/page.js.nft.json +1 -1
- package/.next/server/app/channels.html +2 -2
- package/.next/server/app/channels.rsc +1 -1
- package/.next/server/app/channels.segments/_full.segment.rsc +1 -1
- package/.next/server/app/channels.segments/_head.segment.rsc +1 -1
- package/.next/server/app/channels.segments/_index.segment.rsc +1 -1
- package/.next/server/app/channels.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/channels.segments/channels/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/channels.segments/channels.segment.rsc +1 -1
- package/.next/server/app/cron-jobs/page.js +1 -1
- package/.next/server/app/cron-jobs/page.js.nft.json +1 -1
- package/.next/server/app/cron-jobs.html +1 -1
- package/.next/server/app/cron-jobs.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/_full.segment.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/_index.segment.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/cron-jobs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/cron-jobs.segments/cron-jobs.segment.rsc +1 -1
- package/.next/server/app/goals/[id]/page.js +1 -1
- package/.next/server/app/goals/[id]/page.js.nft.json +1 -1
- package/.next/server/app/goals/new/page.js +1 -1
- package/.next/server/app/goals/new/page.js.nft.json +1 -1
- package/.next/server/app/goals/new.html +2 -2
- package/.next/server/app/goals/new.rsc +1 -1
- package/.next/server/app/goals/new.segments/_full.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/_head.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/_index.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/goals/new/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/goals/new.segment.rsc +1 -1
- package/.next/server/app/goals/new.segments/goals.segment.rsc +1 -1
- package/.next/server/app/goals/page.js +1 -1
- package/.next/server/app/goals/page.js.nft.json +1 -1
- package/.next/server/app/goals.html +1 -1
- package/.next/server/app/goals.rsc +1 -1
- package/.next/server/app/goals.segments/_full.segment.rsc +1 -1
- package/.next/server/app/goals.segments/_head.segment.rsc +1 -1
- package/.next/server/app/goals.segments/_index.segment.rsc +1 -1
- package/.next/server/app/goals.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/goals.segments/goals/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/goals.segments/goals.segment.rsc +1 -1
- package/.next/server/app/page.js +3 -3
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/recipes/[id]/page.js +4 -3
- package/.next/server/app/recipes/[id]/page.js.nft.json +1 -1
- package/.next/server/app/recipes/page.js +4 -3
- package/.next/server/app/recipes/page.js.nft.json +1 -1
- package/.next/server/app/recipes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page.js +1 -1
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +1 -1
- package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/teams/[teamId]/page.js +3 -3
- package/.next/server/app/teams/[teamId]/page.js.nft.json +1 -1
- package/.next/server/app/tickets/[ticket]/page.js +2 -2
- package/.next/server/app/tickets/[ticket]/page.js.nft.json +1 -1
- package/.next/server/app/tickets/page.js +2 -2
- package/.next/server/app/tickets/page.js.nft.json +1 -1
- package/.next/server/app/tickets.html +1 -1
- package/.next/server/app/tickets.rsc +2 -2
- package/.next/server/app/tickets.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tickets.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tickets.segments/_index.segment.rsc +1 -1
- package/.next/server/app/tickets.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/tickets.segments/tickets/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tickets.segments/tickets.segment.rsc +1 -1
- package/.next/server/chunks/[root-of-the-server]__055885ce._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__055885ce._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0c01c5c7._.js +10 -0
- package/.next/server/chunks/[root-of-the-server]__0c01c5c7._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1398a33a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1398a33a._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__159c002b._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__159c002b._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__20c60fb7._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__20c60fb7._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__2588560d._.js +6 -0
- package/.next/server/chunks/[root-of-the-server]__2588560d._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__27293e91._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__27293e91._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__29c85a51._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__29c85a51._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__29fa8108._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__29fa8108._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__2bd44067._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__2bd44067._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__2dd1afff._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__2dd1afff._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__401ab759._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__401ab759._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__422c7160._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__422c7160._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__4670294e._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__4670294e._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__4898071c._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__4898071c._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__4eda99a9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__4eda99a9._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__54478298._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__54478298._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__6dbdb384._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__6dbdb384._.js.map +1 -0
- package/.next/server/chunks/{[root-of-the-server]__dc6c67a5._.js → [root-of-the-server]__74b80ca4._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__94d68aa3._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__94d68aa3._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__9ecbb339._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__9ecbb339._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a27f8405._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a27f8405._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__a6ac3ddf._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__a6ac3ddf._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__b11231a9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__b11231a9._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__b59b3cdd._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__b59b3cdd._.js.map +1 -0
- package/.next/server/chunks/{[root-of-the-server]__94ebcd84._.js → [root-of-the-server]__b5c2b370._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__b955e35a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__b955e35a._.js.map +1 -0
- package/.next/server/chunks/{[root-of-the-server]__920d7db4._.js → [root-of-the-server]__be5f57b2._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__c4ff0427._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__c4ff0427._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__c4ffbb03._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__c4ffbb03._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__d737ca42._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__d737ca42._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__df7df3ac._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__df7df3ac._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__dfca6557._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__dfca6557._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__e6184ba3._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__e6184ba3._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__ed0323e9._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__ed0323e9._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__f585823b._.js +6 -0
- package/.next/server/chunks/[root-of-the-server]__f585823b._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__ff940674._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__ff940674._.js.map +1 -0
- package/.next/server/chunks/src_lib_d2210cbf._.js +3 -0
- package/.next/server/chunks/src_lib_d2210cbf._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__4393e897._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__4393e897._.js.map +1 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__ae77070e._.js → [root-of-the-server]__4c6cc96d._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__4c6cc96d._.js.map +1 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__b6de1782._.js → [root-of-the-server]__507d2fc9._.js} +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__c72e7548._.js → [root-of-the-server]__7180d770._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__7180d770._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__82ce3aee._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__82ce3aee._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__8d24c9c3._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__8d24c9c3._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__bc3b27b0._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__bc3b27b0._.js.map +1 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__72721a7e._.js → [root-of-the-server]__f75a61bf._.js} +2 -2
- package/.next/server/chunks/ssr/_1aad1d9b._.js +24 -0
- package/.next/server/chunks/ssr/_1aad1d9b._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules_next_aefa2538._.js → _da6f800e._.js} +2 -2
- package/.next/server/chunks/ssr/_da6f800e._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_agents_[agentId]_agent-editor_tsx_f85bbe65._.js +1 -1
- package/.next/server/chunks/ssr/src_app_agents_[agentId]_agent-editor_tsx_f85bbe65._.js.map +1 -1
- package/.next/server/chunks/ssr/src_app_recipes_recipes-client_tsx_8ed3ca94._.js +1 -1
- package/.next/server/chunks/ssr/src_app_recipes_recipes-client_tsx_8ed3ca94._.js.map +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/static/chunks/{a33f8641aafb9e7f.js → 54beb791bcc086ae.js} +1 -1
- package/.next/static/chunks/55866d57aa2c7a9c.js +1 -0
- package/openclaw/index.ts +4 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/app/agents/[agentId]/agent-editor.tsx +66 -23
- package/src/app/api/agents/[id]/route.ts +37 -0
- package/src/app/api/agents/add/route.ts +7 -7
- package/src/app/api/agents/files/route.ts +3 -1
- package/src/app/api/agents/skills/install/route.ts +27 -3
- package/src/app/api/agents/skills/route.ts +28 -12
- package/src/app/api/goals/[id]/promote/route.ts +12 -18
- package/src/app/api/recipes/team-agents/route.ts +1 -1
- package/src/app/api/teams/skills/install/route.ts +3 -1
- package/src/app/api/tickets/move/route.ts +3 -4
- package/src/app/recipes/[id]/page.tsx +7 -0
- package/src/app/recipes/page.tsx +7 -0
- package/src/app/recipes/recipes-client.tsx +0 -5
- package/src/lib/agent-workspace.ts +14 -0
- package/src/lib/gateway.ts +5 -8
- package/src/lib/kitchen-api.ts +19 -0
- package/src/lib/openclaw.ts +28 -26
- package/src/lib/paths.ts +4 -3
- package/src/proxy.ts +2 -2
- package/.next/server/app/recipes.html +0 -1
- package/.next/server/app/recipes.meta +0 -15
- package/.next/server/app/recipes.rsc +0 -21
- package/.next/server/app/recipes.segments/_full.segment.rsc +0 -21
- package/.next/server/app/recipes.segments/_head.segment.rsc +0 -6
- package/.next/server/app/recipes.segments/_index.segment.rsc +0 -6
- package/.next/server/app/recipes.segments/_tree.segment.rsc +0 -4
- package/.next/server/app/recipes.segments/recipes/__PAGE__.segment.rsc +0 -10
- package/.next/server/app/recipes.segments/recipes.segment.rsc +0 -4
- package/.next/server/chunks/[root-of-the-server]__02ebb205._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__02ebb205._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__0761ac0a._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0761ac0a._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__0a87d140._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0a87d140._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__13e03a23._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__13e03a23._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__16252fca._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__16252fca._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__1ab15cc6._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1ab15cc6._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__1cb96385._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1cb96385._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__20cb8aee._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__20cb8aee._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__22a29d25._.js +0 -6
- package/.next/server/chunks/[root-of-the-server]__22a29d25._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__2369d373._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__2369d373._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__24fa7b94._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__24fa7b94._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__2c9b0df9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__2c9b0df9._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__2ffbbf0e._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__2ffbbf0e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__394097c4._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__394097c4._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__457a879e._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__457a879e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__4ae35c7d._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__4ae35c7d._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__4d1845bd._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__4d1845bd._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__593499ba._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__593499ba._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__69bcd4b9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__69bcd4b9._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__7f23701b._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__7f23701b._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__8f127b48._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__8f127b48._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__93e05771._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__93e05771._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__9a65704e._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__9a65704e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__b76a826e._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__b76a826e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__baf1631b._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__baf1631b._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__bfd1044e._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__bfd1044e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__c4a25b8f._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__c4a25b8f._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__c4e76686._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__c4e76686._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__c6906128._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__c6906128._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__c8eb444c._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__c8eb444c._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__e28b8399._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__e28b8399._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__e31f8972._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__e31f8972._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__fee3f59e._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__fee3f59e._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__fff0b9c4._.js +0 -6
- package/.next/server/chunks/[root-of-the-server]__fff0b9c4._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__277a8350._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__277a8350._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__7458e8cf._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__7458e8cf._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__8aa0b951._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__8aa0b951._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__91b2c698._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__91b2c698._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__ae77070e._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__c72e7548._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules_next_aefa2538._.js.map +0 -1
- package/.next/static/chunks/4fb7740933125c6a.js +0 -1
- /package/.next/server/chunks/{[root-of-the-server]__dc6c67a5._.js.map → [root-of-the-server]__74b80ca4._.js.map} +0 -0
- /package/.next/server/chunks/{[root-of-the-server]__94ebcd84._.js.map → [root-of-the-server]__b5c2b370._.js.map} +0 -0
- /package/.next/server/chunks/{[root-of-the-server]__920d7db4._.js.map → [root-of-the-server]__be5f57b2._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{[root-of-the-server]__b6de1782._.js.map → [root-of-the-server]__507d2fc9._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{[root-of-the-server]__72721a7e._.js.map → [root-of-the-server]__f75a61bf._.js.map} +0 -0
- /package/.next/static/{8pxUnfVjZMQrso_jWABg7 → uZkSG3UgZ81MwaAQa74zD}/_buildManifest.js +0 -0
- /package/.next/static/{8pxUnfVjZMQrso_jWABg7 → uZkSG3UgZ81MwaAQa74zD}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{8pxUnfVjZMQrso_jWABg7 → uZkSG3UgZ81MwaAQa74zD}/_ssgManifest.js +0 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -109,7 +109,7 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
109
109
|
const [agentFiles, setAgentFiles] = useState<Array<FileEntry & { required?: boolean; rationale?: string }>>([]);
|
|
110
110
|
const [agentFilesLoading, setAgentFilesLoading] = useState(false);
|
|
111
111
|
const [showOptionalFiles, setShowOptionalFiles] = useState(false);
|
|
112
|
-
const [fileName, setFileName] = useState<string>("
|
|
112
|
+
const [fileName, setFileName] = useState<string>("SOUL.md");
|
|
113
113
|
const [fileContent, setFileContent] = useState<string>("");
|
|
114
114
|
|
|
115
115
|
const teamId = agentId.includes("-") ? agentId.split("-").slice(0, -1).join("-") : "";
|
|
@@ -225,8 +225,6 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
225
225
|
setSaving(true);
|
|
226
226
|
setPageMsg("");
|
|
227
227
|
|
|
228
|
-
// Auto-clear after a moment (non-blocking).
|
|
229
|
-
setTimeout(() => setPageMsg(""), 6000);
|
|
230
228
|
try {
|
|
231
229
|
const res = await fetch("/api/agents/update", {
|
|
232
230
|
method: "POST",
|
|
@@ -261,7 +259,6 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
261
259
|
setFileContent(String(json.content ?? ""));
|
|
262
260
|
} catch (e: unknown) {
|
|
263
261
|
setFileError(e instanceof Error ? e.message : String(e));
|
|
264
|
-
setTimeout(() => setFileError(""), 12000);
|
|
265
262
|
} finally {
|
|
266
263
|
setLoadingFile(false);
|
|
267
264
|
}
|
|
@@ -288,6 +285,29 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
288
285
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
289
286
|
}, [activeTab, agentId, agentFiles.length]);
|
|
290
287
|
|
|
288
|
+
function defaultFileContent(name: string) {
|
|
289
|
+
switch (name) {
|
|
290
|
+
case "SOUL.md":
|
|
291
|
+
return "# SOUL.md\n\n";
|
|
292
|
+
case "AGENTS.md":
|
|
293
|
+
return "# AGENTS.md\n\n";
|
|
294
|
+
case "TOOLS.md":
|
|
295
|
+
return "# TOOLS.md\n\n";
|
|
296
|
+
case "STATUS.md":
|
|
297
|
+
return "# STATUS.md\n\n- (empty)\n";
|
|
298
|
+
case "NOTES.md":
|
|
299
|
+
return "# NOTES.md\n\n- (empty)\n";
|
|
300
|
+
case "IDENTITY.md":
|
|
301
|
+
return "# IDENTITY.md\n\n- **Name:**\n- **Creature:**\n- **Vibe:**\n- **Emoji:**\n- **Avatar:**\n";
|
|
302
|
+
case "USER.md":
|
|
303
|
+
return "# USER.md\n\n";
|
|
304
|
+
case "HEARTBEAT.md":
|
|
305
|
+
return "# HEARTBEAT.md\n\n# Keep this file empty (or with only comments) to skip heartbeat API calls.\n";
|
|
306
|
+
default:
|
|
307
|
+
return "";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
291
311
|
async function onSaveAgentFile() {
|
|
292
312
|
setSaving(true);
|
|
293
313
|
setFileError("");
|
|
@@ -299,15 +319,28 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
299
319
|
});
|
|
300
320
|
const json = (await res.json()) as { ok?: boolean; error?: string };
|
|
301
321
|
if (!res.ok || !json.ok) throw new Error(json.error || "Failed to save file");
|
|
322
|
+
|
|
323
|
+
// Refresh the file list so missing/mtime updates immediately.
|
|
324
|
+
const r = await fetch(`/api/agents/files?agentId=${encodeURIComponent(agentId)}`, { cache: "no-store" });
|
|
325
|
+
const j = await r.json();
|
|
326
|
+
if (r.ok && j.ok && Array.isArray(j.files)) {
|
|
327
|
+
setAgentFiles(j.files);
|
|
328
|
+
}
|
|
302
329
|
// No-op: saving a file doesn't need a global notice.
|
|
303
330
|
} catch (e: unknown) {
|
|
304
331
|
setFileError(e instanceof Error ? e.message : String(e));
|
|
305
|
-
setTimeout(() => setFileError(""), 12000);
|
|
306
332
|
} finally {
|
|
307
333
|
setSaving(false);
|
|
308
334
|
}
|
|
309
335
|
}
|
|
310
336
|
|
|
337
|
+
async function onCreateMissingFile(name: string) {
|
|
338
|
+
setFileName(name);
|
|
339
|
+
setFileError("");
|
|
340
|
+
setFileContent(defaultFileContent(name));
|
|
341
|
+
await onSaveAgentFile();
|
|
342
|
+
}
|
|
343
|
+
|
|
311
344
|
async function onDeleteAgent() {
|
|
312
345
|
setDeleteBusy(true);
|
|
313
346
|
setDeleteError(null);
|
|
@@ -533,14 +566,12 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
533
566
|
const json = await res.json();
|
|
534
567
|
if (!res.ok || !json.ok) throw new Error(json.error || "Failed to install skill");
|
|
535
568
|
setSkillMsg(`Installed skill: ${selectedSkill}`);
|
|
536
|
-
setTimeout(() => setSkillMsg(""), 8000);
|
|
537
569
|
// Refresh installed list.
|
|
538
570
|
const r = await fetch(`/api/agents/skills?agentId=${encodeURIComponent(agentId)}`, { cache: "no-store" });
|
|
539
571
|
const j = await r.json();
|
|
540
572
|
if (r.ok && j.ok) setSkillsList(Array.isArray(j.skills) ? j.skills : []);
|
|
541
573
|
} catch (e: unknown) {
|
|
542
574
|
setSkillError(e instanceof Error ? e.message : String(e));
|
|
543
|
-
setTimeout(() => setSkillError(""), 12000);
|
|
544
575
|
} finally {
|
|
545
576
|
setInstallingSkill(false);
|
|
546
577
|
}
|
|
@@ -587,22 +618,34 @@ export default function AgentEditor({ agentId, returnTo }: { agentId: string; re
|
|
|
587
618
|
.filter((f) => (showOptionalFiles ? true : Boolean(f.required) || !f.missing))
|
|
588
619
|
.map((f) => (
|
|
589
620
|
<li key={f.name}>
|
|
590
|
-
<
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
{f.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
621
|
+
<div className="flex items-center gap-2">
|
|
622
|
+
<button
|
|
623
|
+
onClick={() => onLoadAgentFile(f.name)}
|
|
624
|
+
className={
|
|
625
|
+
fileName === f.name
|
|
626
|
+
? "w-full rounded-[var(--ck-radius-sm)] bg-white/10 px-3 py-2 text-left text-sm text-[color:var(--ck-text-primary)]"
|
|
627
|
+
: "w-full rounded-[var(--ck-radius-sm)] px-3 py-2 text-left text-sm text-[color:var(--ck-text-secondary)] hover:bg-white/5"
|
|
628
|
+
}
|
|
629
|
+
>
|
|
630
|
+
<span className={f.required ? "text-[color:var(--ck-text-primary)]" : "text-[color:var(--ck-text-secondary)]"}>
|
|
631
|
+
{f.name}
|
|
632
|
+
</span>
|
|
633
|
+
<span className="ml-2 text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">
|
|
634
|
+
{f.required ? "required" : "optional"}
|
|
635
|
+
</span>
|
|
636
|
+
{f.missing ? <span className="ml-2 text-xs text-[color:var(--ck-text-tertiary)]">missing</span> : null}
|
|
637
|
+
</button>
|
|
638
|
+
{f.missing ? (
|
|
639
|
+
<button
|
|
640
|
+
type="button"
|
|
641
|
+
disabled={saving}
|
|
642
|
+
onClick={() => void onCreateMissingFile(f.name)}
|
|
643
|
+
className="shrink-0 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"
|
|
644
|
+
>
|
|
645
|
+
Create
|
|
646
|
+
</button>
|
|
647
|
+
) : null}
|
|
648
|
+
</div>
|
|
606
649
|
</li>
|
|
607
650
|
))}
|
|
608
651
|
</ul>
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { NextResponse } from "next/server";
|
|
2
4
|
|
|
3
5
|
import { runOpenClaw } from "@/lib/openclaw";
|
|
6
|
+
import { parseTeamRoleWorkspace } from "@/lib/agent-workspace";
|
|
4
7
|
|
|
5
8
|
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
6
9
|
try {
|
|
@@ -8,6 +11,17 @@ export async function DELETE(_req: Request, { params }: { params: Promise<{ id:
|
|
|
8
11
|
const agentId = String(id ?? "").trim();
|
|
9
12
|
if (!agentId) return NextResponse.json({ ok: false, error: "agent id is required" }, { status: 400 });
|
|
10
13
|
|
|
14
|
+
// Resolve workspace BEFORE deleting (after deletion it may disappear from list).
|
|
15
|
+
let workspace: string | null = null;
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await runOpenClaw(["agents", "list", "--json"]);
|
|
18
|
+
const list = JSON.parse(stdout) as Array<{ id: string; workspace?: string }>;
|
|
19
|
+
const agent = list.find((a) => a.id === agentId);
|
|
20
|
+
workspace = agent?.workspace ? String(agent.workspace) : null;
|
|
21
|
+
} catch {
|
|
22
|
+
workspace = null;
|
|
23
|
+
}
|
|
24
|
+
|
|
11
25
|
const result = await runOpenClaw(["agents", "delete", agentId, "--force", "--json"]);
|
|
12
26
|
if (!result.ok) {
|
|
13
27
|
return NextResponse.json(
|
|
@@ -28,6 +42,29 @@ export async function DELETE(_req: Request, { params }: { params: Promise<{ id:
|
|
|
28
42
|
parsed = null;
|
|
29
43
|
}
|
|
30
44
|
|
|
45
|
+
// If this was a team role agent, also remove its role directory.
|
|
46
|
+
// Safer than rm: move to a team-local .trash folder.
|
|
47
|
+
if (workspace) {
|
|
48
|
+
const info = parseTeamRoleWorkspace(workspace);
|
|
49
|
+
if (info.kind === "teamRole") {
|
|
50
|
+
const trashDir = path.join(info.teamDir, ".trash", "roles");
|
|
51
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
52
|
+
const dst = path.join(trashDir, `${info.role}-${ts}`);
|
|
53
|
+
try {
|
|
54
|
+
await fs.mkdir(trashDir, { recursive: true });
|
|
55
|
+
// Only move if the dir exists.
|
|
56
|
+
await fs.rename(info.roleDir, dst);
|
|
57
|
+
} catch {
|
|
58
|
+
// If rename fails (cross-device / missing), fall back to best-effort recursive removal.
|
|
59
|
+
try {
|
|
60
|
+
await fs.rm(info.roleDir, { recursive: true, force: true });
|
|
61
|
+
} catch {
|
|
62
|
+
// ignore
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
31
68
|
return NextResponse.json({ ok: true, result: parsed ?? result.stdout });
|
|
32
69
|
} catch (err: unknown) {
|
|
33
70
|
return NextResponse.json(
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { promisify } from "node:util";
|
|
5
4
|
|
|
6
5
|
import { NextResponse } from "next/server";
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
import { getKitchenApi } from "@/lib/kitchen-api";
|
|
9
8
|
|
|
10
9
|
function normalizeAgentId(id: string) {
|
|
11
10
|
const s = id.trim();
|
|
@@ -32,9 +31,9 @@ export async function POST(req: Request) {
|
|
|
32
31
|
const newAgentId = normalizeAgentId(String(body.newAgentId ?? body.agentId ?? ""));
|
|
33
32
|
const overwrite = Boolean(body.overwrite);
|
|
34
33
|
|
|
35
|
-
const configPath = path.join(
|
|
36
|
-
if (!
|
|
37
|
-
return NextResponse.json({ ok: false, error: "
|
|
34
|
+
const configPath = path.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
35
|
+
if (!configPath.trim()) {
|
|
36
|
+
return NextResponse.json({ ok: false, error: "Could not resolve config path" }, { status: 500 });
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
const raw = await fs.readFile(configPath, "utf8");
|
|
@@ -95,7 +94,8 @@ export async function POST(req: Request) {
|
|
|
95
94
|
await fs.rename(tmpPath, configPath);
|
|
96
95
|
|
|
97
96
|
// Restart gateway so the new agent is live.
|
|
98
|
-
|
|
97
|
+
const api = getKitchenApi();
|
|
98
|
+
await api.runtime.system.runCommandWithTimeout(["openclaw", "gateway", "restart"], { timeoutMs: 120000 });
|
|
99
99
|
|
|
100
100
|
return NextResponse.json({ ok: true, agentId: newAgentId, workspace: newWorkspace, restarted: true });
|
|
101
101
|
} catch (err) {
|
|
@@ -26,11 +26,13 @@ export async function GET(req: Request) {
|
|
|
26
26
|
|
|
27
27
|
// Required vs optional classification to avoid "missing" noise.
|
|
28
28
|
const candidates: Array<{ name: string; required: boolean; rationale: string }> = [
|
|
29
|
-
{ name: "IDENTITY.md", required: true, rationale: "Identity (name/emoji/avatar)" },
|
|
30
29
|
{ name: "SOUL.md", required: true, rationale: "Agent persona/instructions" },
|
|
31
30
|
{ name: "AGENTS.md", required: true, rationale: "Agent operating rules" },
|
|
32
31
|
{ name: "TOOLS.md", required: true, rationale: "Agent local notes" },
|
|
33
32
|
|
|
33
|
+
{ name: "STATUS.md", required: false, rationale: "Optional current status snapshot" },
|
|
34
|
+
{ name: "NOTES.md", required: false, rationale: "Optional scratchpad" },
|
|
35
|
+
{ name: "IDENTITY.md", required: false, rationale: "Optional identity (name/emoji/avatar)" },
|
|
34
36
|
{ name: "USER.md", required: false, rationale: "Optional user profile" },
|
|
35
37
|
{ name: "HEARTBEAT.md", required: false, rationale: "Optional periodic checklist" },
|
|
36
38
|
];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { runOpenClaw } from "@/lib/openclaw";
|
|
3
|
+
import { parseTeamRoleWorkspace } from "@/lib/agent-workspace";
|
|
3
4
|
|
|
4
5
|
export async function POST(req: Request) {
|
|
5
6
|
const body = (await req.json()) as { agentId?: string; skill?: string };
|
|
@@ -9,14 +10,37 @@ export async function POST(req: Request) {
|
|
|
9
10
|
if (!agentId) return NextResponse.json({ ok: false, error: "agentId is required" }, { status: 400 });
|
|
10
11
|
if (!skill) return NextResponse.json({ ok: false, error: "skill is required" }, { status: 400 });
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
// For role-based team agents, install at team scope to avoid creating a separate
|
|
14
|
+
// workspace-<agentId> directory that diverges from roles/<role>.
|
|
15
|
+
let args = ["recipes", "install-skill", skill, "--agent-id", agentId, "--yes"];
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await runOpenClaw(["agents", "list", "--json"]);
|
|
18
|
+
const list = JSON.parse(stdout) as Array<{ id: string; workspace?: string }>;
|
|
19
|
+
const agent = list.find((a) => a.id === agentId);
|
|
20
|
+
const ws = agent?.workspace ? String(agent.workspace) : "";
|
|
21
|
+
const info = parseTeamRoleWorkspace(ws);
|
|
22
|
+
if (info.kind === "teamRole") {
|
|
23
|
+
args = ["recipes", "install-skill", skill, "--team-id", info.teamId, "--yes"];
|
|
24
|
+
}
|
|
25
|
+
} catch {
|
|
26
|
+
// If anything goes wrong, fall back to agent scope.
|
|
27
|
+
}
|
|
28
|
+
|
|
13
29
|
const res = await runOpenClaw(args);
|
|
14
30
|
if (!res.ok) {
|
|
31
|
+
const stdout = res.stdout?.trim();
|
|
32
|
+
const stderr = res.stderr?.trim();
|
|
15
33
|
return NextResponse.json(
|
|
16
|
-
{
|
|
34
|
+
{
|
|
35
|
+
ok: false,
|
|
36
|
+
error: stderr || stdout || `openclaw ${args.join(" ")} failed (exit=${res.exitCode})`,
|
|
37
|
+
stdout: res.stdout,
|
|
38
|
+
stderr: res.stderr,
|
|
39
|
+
scopeArgs: args,
|
|
40
|
+
},
|
|
17
41
|
{ status: 500 },
|
|
18
42
|
);
|
|
19
43
|
}
|
|
20
44
|
|
|
21
|
-
return NextResponse.json({ ok: true, agentId, skill, stdout: res.stdout, stderr: res.stderr });
|
|
45
|
+
return NextResponse.json({ ok: true, agentId, skill, scopeArgs: args, stdout: res.stdout, stderr: res.stderr });
|
|
22
46
|
}
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { NextResponse } from "next/server";
|
|
4
4
|
import { runOpenClaw } from "@/lib/openclaw";
|
|
5
|
+
import { parseTeamRoleWorkspace } from "@/lib/agent-workspace";
|
|
5
6
|
|
|
6
7
|
type AgentListItem = { id: string; workspace?: string };
|
|
7
8
|
|
|
@@ -19,17 +20,32 @@ export async function GET(req: Request) {
|
|
|
19
20
|
if (!agentId) return NextResponse.json({ ok: false, error: "agentId is required" }, { status: 400 });
|
|
20
21
|
|
|
21
22
|
const ws = await resolveAgentWorkspace(agentId);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.map((e) => e.name)
|
|
29
|
-
.sort((a, b) => a.localeCompare(b));
|
|
30
|
-
|
|
31
|
-
return NextResponse.json({ ok: true, agentId, workspace: ws, skillsDir, skills });
|
|
32
|
-
} catch (e: unknown) {
|
|
33
|
-
return NextResponse.json({ ok: true, agentId, workspace: ws, skillsDir, skills: [], note: e instanceof Error ? e.message : String(e) });
|
|
23
|
+
|
|
24
|
+
const info = parseTeamRoleWorkspace(ws);
|
|
25
|
+
const dirs: string[] = [path.join(ws, "skills")];
|
|
26
|
+
if (info.kind === "teamRole") {
|
|
27
|
+
// If skills were installed at the team scope, surface them for the role agent too.
|
|
28
|
+
dirs.push(path.join(info.teamDir, "skills"));
|
|
34
29
|
}
|
|
30
|
+
|
|
31
|
+
const skills = new Set<string>();
|
|
32
|
+
const notes: string[] = [];
|
|
33
|
+
|
|
34
|
+
for (const skillsDir of dirs) {
|
|
35
|
+
try {
|
|
36
|
+
const entries = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
37
|
+
for (const e of entries) if (e.isDirectory()) skills.add(e.name);
|
|
38
|
+
} catch (e: unknown) {
|
|
39
|
+
notes.push(`${skillsDir}: ${e instanceof Error ? e.message : String(e)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return NextResponse.json({
|
|
44
|
+
ok: true,
|
|
45
|
+
agentId,
|
|
46
|
+
workspace: ws,
|
|
47
|
+
skillsDirs: dirs,
|
|
48
|
+
skills: Array.from(skills).sort((a, b) => a.localeCompare(b)),
|
|
49
|
+
note: notes.length ? notes.join("; ") : undefined,
|
|
50
|
+
});
|
|
35
51
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
import { promisify } from "node:util";
|
|
5
3
|
|
|
6
4
|
import { NextResponse } from "next/server";
|
|
7
5
|
|
|
8
6
|
import { readGoal, writeGoal } from "@/lib/goals";
|
|
9
7
|
import { getTeamWorkspaceDir, readOpenClawConfig } from "@/lib/paths";
|
|
10
|
-
|
|
11
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
+
import { runOpenClaw } from "@/lib/openclaw";
|
|
12
9
|
|
|
13
10
|
function slugifyFilePart(input: string) {
|
|
14
11
|
return input
|
|
@@ -122,20 +119,17 @@ export async function POST(_: Request, { params }: { params: Promise<{ id: strin
|
|
|
122
119
|
} else {
|
|
123
120
|
pingAttempted = true;
|
|
124
121
|
try {
|
|
125
|
-
await
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
],
|
|
137
|
-
{ timeout: 70000 },
|
|
138
|
-
);
|
|
122
|
+
const res = await runOpenClaw([
|
|
123
|
+
"agent",
|
|
124
|
+
"--agent",
|
|
125
|
+
targetAgentId,
|
|
126
|
+
"--message",
|
|
127
|
+
`New goal promoted to development-team inbox: ${updated.frontmatter.title} (${goalId}). Inbox file: ${inboxPath}`,
|
|
128
|
+
"--timeout",
|
|
129
|
+
"60",
|
|
130
|
+
"--json",
|
|
131
|
+
]);
|
|
132
|
+
if (!res.ok) throw new Error(res.stderr || `openclaw exit ${res.exitCode}`);
|
|
139
133
|
pingOk = true;
|
|
140
134
|
} catch (e: unknown) {
|
|
141
135
|
pingReason = e instanceof Error ? e.message : String(e);
|
|
@@ -65,7 +65,7 @@ export async function POST(req: Request) {
|
|
|
65
65
|
templatesRaw && typeof templatesRaw === "object" && !Array.isArray(templatesRaw)
|
|
66
66
|
? (templatesRaw as Record<string, unknown>)
|
|
67
67
|
: {};
|
|
68
|
-
|
|
68
|
+
const nextTemplates: Record<string, unknown> = { ...templates };
|
|
69
69
|
|
|
70
70
|
if (op === "remove") {
|
|
71
71
|
const role = normalizeRole(String(body.role ?? ""));
|
|
@@ -12,10 +12,12 @@ export async function POST(req: Request) {
|
|
|
12
12
|
const args = ["recipes", "install-skill", skill, "--team-id", teamId, "--yes"];
|
|
13
13
|
const res = await runOpenClaw(args);
|
|
14
14
|
if (!res.ok) {
|
|
15
|
+
const stdout = res.stdout?.trim();
|
|
16
|
+
const stderr = res.stderr?.trim();
|
|
15
17
|
return NextResponse.json(
|
|
16
18
|
{
|
|
17
19
|
ok: false,
|
|
18
|
-
error:
|
|
20
|
+
error: stderr || stdout || `openclaw ${args.join(" ")} failed (exit=${res.exitCode})`,
|
|
19
21
|
stdout: res.stdout,
|
|
20
22
|
stderr: res.stderr,
|
|
21
23
|
},
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import { execFile } from "node:child_process";
|
|
3
|
-
import { promisify } from "node:util";
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import { runOpenClaw } from "@/lib/openclaw";
|
|
6
4
|
|
|
7
5
|
export async function POST(req: Request) {
|
|
8
6
|
try {
|
|
@@ -29,7 +27,8 @@ export async function POST(req: Request) {
|
|
|
29
27
|
"--yes",
|
|
30
28
|
];
|
|
31
29
|
|
|
32
|
-
await
|
|
30
|
+
const res = await runOpenClaw(args);
|
|
31
|
+
if (!res.ok) throw new Error(res.stderr || `openclaw exit ${res.exitCode}`);
|
|
33
32
|
|
|
34
33
|
return NextResponse.json({ ok: true });
|
|
35
34
|
} catch (err: unknown) {
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
+
import { unstable_noStore as noStore } from "next/cache";
|
|
3
|
+
|
|
2
4
|
import { runOpenClaw } from "@/lib/openclaw";
|
|
3
5
|
import RecipeEditor from "./RecipeEditor";
|
|
4
6
|
|
|
7
|
+
export const dynamic = "force-dynamic";
|
|
8
|
+
export const revalidate = 0;
|
|
9
|
+
|
|
5
10
|
type RecipeListItem = {
|
|
6
11
|
id: string;
|
|
7
12
|
name: string;
|
|
@@ -21,6 +26,8 @@ async function getKind(id: string): Promise<"agent" | "team" | null> {
|
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export default async function RecipePage({ params }: { params: Promise<{ id: string }> }) {
|
|
29
|
+
noStore();
|
|
30
|
+
|
|
24
31
|
const { id } = await params;
|
|
25
32
|
const kind = await getKind(id);
|
|
26
33
|
|
package/src/app/recipes/page.tsx
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import Link from "next/link";
|
|
2
|
+
import { unstable_noStore as noStore } from "next/cache";
|
|
3
|
+
|
|
2
4
|
import { runOpenClaw } from "@/lib/openclaw";
|
|
3
5
|
import RecipesClient from "./recipes-client";
|
|
4
6
|
|
|
7
|
+
export const dynamic = "force-dynamic";
|
|
8
|
+
export const revalidate = 0;
|
|
9
|
+
|
|
5
10
|
type Recipe = {
|
|
6
11
|
id: string;
|
|
7
12
|
name: string;
|
|
@@ -39,6 +44,8 @@ async function getAgents(): Promise<{ agentIds: string[]; error: string | null }
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
export default async function RecipesPage() {
|
|
47
|
+
noStore();
|
|
48
|
+
|
|
42
49
|
const [{ recipes, error }, { agentIds }] = await Promise.all([getRecipes(), getAgents()]);
|
|
43
50
|
|
|
44
51
|
const builtin = recipes.filter((r) => r.source === "builtin");
|
|
@@ -126,7 +126,6 @@ export default function RecipesClient({
|
|
|
126
126
|
|
|
127
127
|
const [overlayOpen, setOverlayOpen] = useState(false);
|
|
128
128
|
const [overlayStep, setOverlayStep] = useState<ScaffoldOverlayStep>(1);
|
|
129
|
-
const [overlayDetails, setOverlayDetails] = useState<string>("");
|
|
130
129
|
const router = useRouter();
|
|
131
130
|
|
|
132
131
|
const [deleteOpen, setDeleteOpen] = useState(false);
|
|
@@ -266,7 +265,6 @@ export default function RecipesClient({
|
|
|
266
265
|
|
|
267
266
|
setOverlayOpen(true);
|
|
268
267
|
setOverlayStep(1);
|
|
269
|
-
setOverlayDetails("");
|
|
270
268
|
|
|
271
269
|
let serveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
272
270
|
|
|
@@ -295,7 +293,6 @@ export default function RecipesClient({
|
|
|
295
293
|
}, 20_000);
|
|
296
294
|
|
|
297
295
|
const stderr = typeof json.stderr === "string" ? json.stderr : "";
|
|
298
|
-
if (stderr.trim()) setOverlayDetails(stderr.trim());
|
|
299
296
|
|
|
300
297
|
// Some CLI failures currently still surface as { ok: true, stderr: "...Error: ..." }.
|
|
301
298
|
// Treat those as hard failures so we don't navigate into a broken team page.
|
|
@@ -361,7 +358,6 @@ export default function RecipesClient({
|
|
|
361
358
|
|
|
362
359
|
setOverlayOpen(true);
|
|
363
360
|
setOverlayStep(1);
|
|
364
|
-
setOverlayDetails("");
|
|
365
361
|
|
|
366
362
|
let serveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
367
363
|
|
|
@@ -388,7 +384,6 @@ export default function RecipesClient({
|
|
|
388
384
|
}, 20_000);
|
|
389
385
|
|
|
390
386
|
const stderr = typeof json.stderr === "string" ? json.stderr : "";
|
|
391
|
-
if (stderr.trim()) setOverlayDetails(stderr.trim());
|
|
392
387
|
|
|
393
388
|
if (/Failed to start CLI:/i.test(stderr) || /\bError: /i.test(stderr)) {
|
|
394
389
|
throw new Error(stderr.trim() || "Scaffold failed");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
export function parseTeamRoleWorkspace(ws: string):
|
|
4
|
+
| { kind: "teamRole"; teamDir: string; teamId: string; roleDir: string; role: string }
|
|
5
|
+
| { kind: "other" } {
|
|
6
|
+
const normalized = ws.replace(/\\/g, "/");
|
|
7
|
+
const m = normalized.match(/^(.*\/workspace-([^\/]+))\/roles\/([^\/]+)\/?$/);
|
|
8
|
+
if (!m) return { kind: "other" };
|
|
9
|
+
const teamDir = m[1];
|
|
10
|
+
const teamId = m[2];
|
|
11
|
+
const role = m[3];
|
|
12
|
+
const roleDir = path.join(teamDir, "roles", role);
|
|
13
|
+
return { kind: "teamRole", teamDir, teamId, roleDir, role };
|
|
14
|
+
}
|
package/src/lib/gateway.ts
CHANGED
|
@@ -27,17 +27,14 @@ type ToolTextEnvelope = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
async function getGatewayBaseUrlAndToken() {
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
const envUrl = (process.env.OPENCLAW_GATEWAY_HTTP_URL || process.env.OPENCLAW_GATEWAY_URL || "").trim();
|
|
33
|
-
const envToken = (process.env.OPENCLAW_GATEWAY_TOKEN || "").trim();
|
|
34
|
-
|
|
30
|
+
// ClawKitchen runs in-process with the OpenClaw Gateway (as a plugin), so we can read
|
|
31
|
+
// the gateway port/token from the loaded config.
|
|
35
32
|
const cfg = await readOpenClawConfig();
|
|
36
33
|
const port = cfg.gateway?.port ?? 18789;
|
|
37
|
-
const token =
|
|
38
|
-
if (!token) throw new Error("Missing gateway token
|
|
34
|
+
const token = cfg.gateway?.auth?.token;
|
|
35
|
+
if (!token) throw new Error("Missing gateway token (gateway.auth.token in ~/.openclaw/openclaw.json)");
|
|
39
36
|
|
|
40
|
-
const baseUrl =
|
|
37
|
+
const baseUrl = `http://127.0.0.1:${port}`;
|
|
41
38
|
return { baseUrl, token };
|
|
42
39
|
}
|
|
43
40
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// NOTE: This file is compiled by Next.js.
|
|
2
|
+
// Do not import `openclaw/plugin-sdk` here (it is provided by the gateway runtime, not as an npm dep).
|
|
3
|
+
|
|
4
|
+
type KitchenApi = {
|
|
5
|
+
config: unknown;
|
|
6
|
+
runtime: {
|
|
7
|
+
system: { runCommandWithTimeout: (argv: string[], opts: { timeoutMs: number }) => Promise<{ stdout?: string; stderr?: string }> };
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function getKitchenApi(): KitchenApi {
|
|
12
|
+
const api = (globalThis as unknown as { __clawkitchen_api?: KitchenApi }).__clawkitchen_api;
|
|
13
|
+
if (!api) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
"ClawKitchen: OpenClaw plugin API not available. (This should only happen if Kitchen is started outside the gateway process.)",
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return api;
|
|
19
|
+
}
|