slackhive 0.1.37 → 0.1.39
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/.dockerignore +14 -0
- package/.env.example +44 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +65 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +27 -0
- package/.github/dependabot.yml +20 -0
- package/.github/workflows/audit.yml +149 -0
- package/.github/workflows/ci.yml +135 -0
- package/CHANGELOG.md +52 -0
- package/CODE_OF_CONDUCT.md +37 -0
- package/CONTRIBUTING.md +204 -0
- package/LICENSE +21 -0
- package/README.md +19 -0
- package/SECURITY.md +47 -0
- package/apps/runner/Dockerfile +33 -0
- package/apps/runner/dist/__tests__/channel-restrictions.test.d.ts +8 -0
- package/apps/runner/dist/__tests__/channel-restrictions.test.js +63 -0
- package/apps/runner/dist/__tests__/channel-restrictions.test.js.map +1 -0
- package/apps/runner/dist/__tests__/claude-handler-resolve.test.d.ts +20 -0
- package/apps/runner/dist/__tests__/claude-handler-resolve.test.js +178 -0
- package/apps/runner/dist/__tests__/claude-handler-resolve.test.js.map +1 -0
- package/apps/runner/dist/__tests__/compile-claude-md.test.d.ts +13 -0
- package/apps/runner/dist/__tests__/compile-claude-md.test.js +144 -0
- package/apps/runner/dist/__tests__/compile-claude-md.test.js.map +1 -0
- package/apps/runner/dist/__tests__/memory-sync.test.d.ts +11 -0
- package/apps/runner/dist/__tests__/memory-sync.test.js +56 -0
- package/apps/runner/dist/__tests__/memory-sync.test.js.map +1 -0
- package/apps/runner/dist/__tests__/slack-file-support.test.d.ts +9 -0
- package/apps/runner/dist/__tests__/slack-file-support.test.js +271 -0
- package/apps/runner/dist/__tests__/slack-file-support.test.js.map +1 -0
- package/apps/runner/dist/__tests__/slack-formatting.test.d.ts +12 -0
- package/apps/runner/dist/__tests__/slack-formatting.test.js +400 -0
- package/apps/runner/dist/__tests__/slack-formatting.test.js.map +1 -0
- package/apps/runner/dist/__tests__/thread-context.test.d.ts +12 -0
- package/apps/runner/dist/__tests__/thread-context.test.js +182 -0
- package/apps/runner/dist/__tests__/thread-context.test.js.map +1 -0
- package/apps/runner/dist/agent-runner.d.ts +118 -0
- package/apps/runner/dist/agent-runner.js +352 -0
- package/apps/runner/dist/agent-runner.js.map +1 -0
- package/apps/runner/dist/claude-handler.d.ts +122 -0
- package/apps/runner/dist/claude-handler.js +402 -0
- package/apps/runner/dist/claude-handler.js.map +1 -0
- package/apps/runner/dist/compile-claude-md.d.ts +59 -0
- package/apps/runner/dist/compile-claude-md.js +291 -0
- package/apps/runner/dist/compile-claude-md.js.map +1 -0
- package/apps/runner/dist/correction-handler.d.ts +46 -0
- package/apps/runner/dist/correction-handler.js +162 -0
- package/apps/runner/dist/correction-handler.js.map +1 -0
- package/apps/runner/dist/correction-manager.d.ts +53 -0
- package/apps/runner/dist/correction-manager.js +241 -0
- package/apps/runner/dist/correction-manager.js.map +1 -0
- package/apps/runner/dist/db.d.ts +193 -0
- package/apps/runner/dist/db.js +492 -0
- package/apps/runner/dist/db.js.map +1 -0
- package/apps/runner/dist/index.d.ts +9 -0
- package/apps/runner/dist/index.js +43 -0
- package/apps/runner/dist/index.js.map +1 -0
- package/apps/runner/dist/job-scheduler.d.ts +57 -0
- package/apps/runner/dist/job-scheduler.js +150 -0
- package/apps/runner/dist/job-scheduler.js.map +1 -0
- package/apps/runner/dist/logger.d.ts +32 -0
- package/apps/runner/dist/logger.js +52 -0
- package/apps/runner/dist/logger.js.map +1 -0
- package/apps/runner/dist/mcp-process-manager.d.ts +38 -0
- package/apps/runner/dist/mcp-process-manager.js +189 -0
- package/apps/runner/dist/mcp-process-manager.js.map +1 -0
- package/apps/runner/dist/memory-mcp.d.ts +14 -0
- package/apps/runner/dist/memory-mcp.js +88 -0
- package/apps/runner/dist/memory-mcp.js.map +1 -0
- package/apps/runner/dist/memory-watcher.d.ts +78 -0
- package/apps/runner/dist/memory-watcher.js +220 -0
- package/apps/runner/dist/memory-watcher.js.map +1 -0
- package/apps/runner/dist/slack-handler.d.ts +120 -0
- package/apps/runner/dist/slack-handler.js +843 -0
- package/apps/runner/dist/slack-handler.js.map +1 -0
- package/apps/runner/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/apps/runner/package.json +42 -0
- package/apps/runner/src/__tests__/channel-restrictions.test.ts +75 -0
- package/apps/runner/src/__tests__/claude-handler-resolve.test.ts +160 -0
- package/apps/runner/src/__tests__/compile-claude-md.test.ts +139 -0
- package/apps/runner/src/__tests__/memory-sync.test.ts +59 -0
- package/apps/runner/src/__tests__/slack-file-support.test.ts +376 -0
- package/apps/runner/src/__tests__/slack-formatting.test.ts +495 -0
- package/apps/runner/src/__tests__/thread-context.test.ts +215 -0
- package/apps/runner/src/agent-runner.ts +397 -0
- package/apps/runner/src/claude-handler.ts +475 -0
- package/apps/runner/src/compile-claude-md.ts +283 -0
- package/apps/runner/src/correction-handler.ts +191 -0
- package/apps/runner/src/correction-manager.ts +285 -0
- package/apps/runner/src/db.ts +604 -0
- package/apps/runner/src/index.ts +46 -0
- package/apps/runner/src/job-scheduler.ts +165 -0
- package/apps/runner/src/logger.ts +49 -0
- package/apps/runner/src/mcp-process-manager.ts +195 -0
- package/apps/runner/src/memory-mcp.ts +85 -0
- package/apps/runner/src/memory-watcher.ts +215 -0
- package/apps/runner/src/slack-handler.ts +929 -0
- package/apps/runner/tsconfig.json +17 -0
- package/apps/runner/vitest.config.mts +17 -0
- package/apps/web/.eslintrc.json +3 -0
- package/apps/web/.next/app-build-manifest.json +323 -0
- package/apps/web/.next/app-path-routes-manifest.json +46 -0
- package/apps/web/.next/build-manifest.json +33 -0
- package/apps/web/.next/cache/.previewinfo +1 -0
- package/apps/web/.next/cache/.rscinfo +1 -0
- package/apps/web/.next/cache/webpack/client-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/1.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/2.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/3.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/4.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/1.pack +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/apps/web/.next/cache/webpack/server-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/1.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/2.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/apps/web/.next/diagnostics/build-diagnostics.json +6 -0
- package/apps/web/.next/diagnostics/framework.json +1 -0
- package/apps/web/.next/package.json +1 -0
- package/apps/web/.next/react-loadable-manifest.json +1 -0
- package/apps/web/.next/server/app/_not-found/page.js +2 -0
- package/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/agents/[slug]/page.js +4 -0
- package/apps/web/.next/server/app/agents/[slug]/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/agents/[slug]/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/agents/new/page.js +2 -0
- package/apps/web/.next/server/app/agents/new/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/agents/new/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/access/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/access/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/access/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/claude-md/route.js +6 -0
- package/apps/web/.next/server/app/api/agents/[id]/claude-md/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/claude-md/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/logs/route.js +3 -0
- package/apps/web/.next/server/app/api/agents/[id]/logs/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/logs/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/manifest/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/manifest/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/manifest/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/mcps/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/mcps/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/mcps/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/memories/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/permissions/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/permissions/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/permissions/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/reload/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/reload/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/reload/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/restrictions/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/restrictions/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/restrictions/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/route.js +33 -0
- package/apps/web/.next/server/app/api/agents/[id]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/skills/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/slack-info/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/slack-info/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/slack-info/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/snapshots/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/start/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/start/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/start/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/stop/route.js +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/stop/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/[id]/stop/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/agents/route.js +91 -0
- package/apps/web/.next/server/app/api/agents/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/agents/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/auth/login/route.js +1 -0
- package/apps/web/.next/server/app/api/auth/login/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/auth/logout/route.js +1 -0
- package/apps/web/.next/server/app/api/auth/logout/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/auth/me/route.js +1 -0
- package/apps/web/.next/server/app/api/auth/me/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/auth/users/[id]/route.js +1 -0
- package/apps/web/.next/server/app/api/auth/users/[id]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/auth/users/[id]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/auth/users/route.js +1 -0
- package/apps/web/.next/server/app/api/auth/users/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/auth/users/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/env-vars/[key]/route.js +1 -0
- package/apps/web/.next/server/app/api/env-vars/[key]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/env-vars/[key]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/env-vars/route.js +1 -0
- package/apps/web/.next/server/app/api/env-vars/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/env-vars/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/route.js +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/runs/route.js +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/runs/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/jobs/[id]/runs/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/jobs/route.js +1 -0
- package/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/jobs/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/route.js +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/test/route.js +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/test/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/mcps/[id]/test/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/mcps/route.js +1 -0
- package/apps/web/.next/server/app/api/mcps/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/mcps/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/api/settings/route.js +1 -0
- package/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/api/settings/route_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/icon.svg/route.js +1 -0
- package/apps/web/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/apps/web/.next/server/app/jobs/page.js +2 -0
- package/apps/web/.next/server/app/jobs/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/jobs/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/login/page.js +2 -0
- package/apps/web/.next/server/app/login/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/login/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/page.js +2 -0
- package/apps/web/.next/server/app/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/settings/env-vars/page.js +2 -0
- package/apps/web/.next/server/app/settings/env-vars/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/settings/env-vars/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/settings/mcps/page.js +2 -0
- package/apps/web/.next/server/app/settings/mcps/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/settings/mcps/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app/settings/page.js +2 -0
- package/apps/web/.next/server/app/settings/page.js.nft.json +1 -0
- package/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -0
- package/apps/web/.next/server/app-paths-manifest.json +46 -0
- package/apps/web/.next/server/chunks/1157.js +9 -0
- package/apps/web/.next/server/chunks/2287.js +1 -0
- package/apps/web/.next/server/chunks/3444.js +1 -0
- package/apps/web/.next/server/chunks/383.js +6 -0
- package/apps/web/.next/server/chunks/4012.js +58 -0
- package/apps/web/.next/server/chunks/6791.js +1 -0
- package/apps/web/.next/server/chunks/7171.js +1 -0
- package/apps/web/.next/server/chunks/8819.js +22 -0
- package/apps/web/.next/server/edge-runtime-webpack.js +2 -0
- package/apps/web/.next/server/edge-runtime-webpack.js.map +1 -0
- package/apps/web/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/apps/web/.next/server/middleware-build-manifest.js +1 -0
- package/apps/web/.next/server/middleware-manifest.json +32 -0
- package/apps/web/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/apps/web/.next/server/next-font-manifest.js +1 -0
- package/apps/web/.next/server/next-font-manifest.json +1 -0
- package/apps/web/.next/server/pages/_app.js +1 -0
- package/apps/web/.next/server/pages/_app.js.nft.json +1 -0
- package/apps/web/.next/server/pages/_document.js +1 -0
- package/apps/web/.next/server/pages/_document.js.nft.json +1 -0
- package/apps/web/.next/server/pages/_error.js +19 -0
- package/apps/web/.next/server/pages/_error.js.nft.json +1 -0
- package/apps/web/.next/server/pages-manifest.json +5 -0
- package/apps/web/.next/server/server-reference-manifest.js +1 -0
- package/apps/web/.next/server/server-reference-manifest.json +1 -0
- package/apps/web/.next/server/src/middleware.js +14 -0
- package/apps/web/.next/server/src/middleware.js.map +1 -0
- package/apps/web/.next/server/webpack-runtime.js +1 -0
- package/apps/web/.next/static/chunks/18-90b700ea37b686a2.js +1 -0
- package/apps/web/.next/static/chunks/87c73c54-24122e7b92478d00.js +1 -0
- package/apps/web/.next/static/chunks/9664-af80478aa73ba424.js +1 -0
- package/apps/web/.next/static/chunks/app/_not-found/page-b9cee17ed89ca24a.js +1 -0
- package/apps/web/.next/static/chunks/app/agents/[slug]/page-18369fc3fe1a9a7b.js +1 -0
- package/apps/web/.next/static/chunks/app/agents/new/page-bf11cf8901c7e2cd.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/access/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/claude-md/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/logs/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/manifest/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/mcps/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/memories/[memId]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/memories/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/permissions/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/reload/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/restrictions/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/skills/[skillId]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/skills/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/slack-info/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/[sid]/restore/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/[sid]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/start/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/[id]/stop/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/agents/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/auth/login/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/auth/logout/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/auth/me/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/auth/users/[id]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/auth/users/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/env-vars/[key]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/env-vars/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/jobs/[id]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/jobs/[id]/runs/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/jobs/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/mcps/[id]/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/mcps/[id]/test/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/mcps/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/api/settings/route-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/jobs/page-f5aa89a47c50efd8.js +1 -0
- package/apps/web/.next/static/chunks/app/layout-2079f4964aa7314e.js +1 -0
- package/apps/web/.next/static/chunks/app/login/layout-07f0f73ac9839899.js +1 -0
- package/apps/web/.next/static/chunks/app/login/page-aa259283dc38e8f9.js +1 -0
- package/apps/web/.next/static/chunks/app/page-e83437b608104dff.js +1 -0
- package/apps/web/.next/static/chunks/app/settings/env-vars/page-06479dbdfb78b76b.js +1 -0
- package/apps/web/.next/static/chunks/app/settings/mcps/page-75650686ed6490c7.js +1 -0
- package/apps/web/.next/static/chunks/app/settings/page-e1e62fc41ff6cddd.js +1 -0
- package/apps/web/.next/static/chunks/framework-811407f832a33072.js +1 -0
- package/apps/web/.next/static/chunks/main-3f1cddbdd67b1546.js +1 -0
- package/apps/web/.next/static/chunks/main-app-cebd8a6a5ccbf72d.js +1 -0
- package/apps/web/.next/static/chunks/pages/_app-50fa07b56b2d29ac.js +1 -0
- package/apps/web/.next/static/chunks/pages/_error-fed8688bdd23f211.js +1 -0
- package/apps/web/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/apps/web/.next/static/chunks/webpack-6c05566dba553c97.js +1 -0
- package/apps/web/.next/static/css/15371687405525e2.css +5 -0
- package/apps/web/.next/static/ikfNbLhuw7jntn35bz0lk/_buildManifest.js +1 -0
- package/apps/web/.next/static/ikfNbLhuw7jntn35bz0lk/_ssgManifest.js +1 -0
- package/apps/web/.next/trace +5 -0
- package/apps/web/.next/types/app/agents/[slug]/page.ts +84 -0
- package/apps/web/.next/types/app/agents/new/page.ts +84 -0
- package/apps/web/.next/types/app/api/agents/[id]/access/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/claude-md/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/logs/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/manifest/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/mcps/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/memories/[memId]/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/memories/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/permissions/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/reload/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/restrictions/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/skills/[skillId]/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/skills/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/slack-info/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/snapshots/[sid]/restore/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/snapshots/[sid]/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/snapshots/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/start/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/[id]/stop/route.ts +347 -0
- package/apps/web/.next/types/app/api/agents/route.ts +347 -0
- package/apps/web/.next/types/app/api/auth/login/route.ts +347 -0
- package/apps/web/.next/types/app/api/auth/logout/route.ts +347 -0
- package/apps/web/.next/types/app/api/auth/me/route.ts +347 -0
- package/apps/web/.next/types/app/api/auth/users/[id]/route.ts +347 -0
- package/apps/web/.next/types/app/api/auth/users/route.ts +347 -0
- package/apps/web/.next/types/app/api/env-vars/[key]/route.ts +347 -0
- package/apps/web/.next/types/app/api/env-vars/route.ts +347 -0
- package/apps/web/.next/types/app/api/jobs/[id]/route.ts +347 -0
- package/apps/web/.next/types/app/api/jobs/[id]/runs/route.ts +347 -0
- package/apps/web/.next/types/app/api/jobs/route.ts +347 -0
- package/apps/web/.next/types/app/api/mcps/[id]/route.ts +347 -0
- package/apps/web/.next/types/app/api/mcps/[id]/test/route.ts +347 -0
- package/apps/web/.next/types/app/api/mcps/route.ts +347 -0
- package/apps/web/.next/types/app/api/settings/route.ts +347 -0
- package/apps/web/.next/types/app/jobs/page.ts +84 -0
- package/apps/web/.next/types/app/login/layout.ts +84 -0
- package/apps/web/.next/types/app/login/page.ts +84 -0
- package/apps/web/.next/types/app/page.ts +84 -0
- package/apps/web/.next/types/app/settings/env-vars/page.ts +84 -0
- package/apps/web/.next/types/app/settings/mcps/page.ts +84 -0
- package/apps/web/.next/types/app/settings/page.ts +84 -0
- package/apps/web/.next/types/cache-life.d.ts +141 -0
- package/apps/web/.next/types/package.json +1 -0
- package/apps/web/.next/types/routes.d.ts +114 -0
- package/apps/web/.next/types/validator.ts +448 -0
- package/apps/web/Dockerfile +37 -0
- package/apps/web/next-env.d.ts +6 -0
- package/apps/web/next.config.js +6 -0
- package/apps/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/apps/web/package.json +48 -0
- package/apps/web/postcss.config.js +3 -0
- package/apps/web/public/logo.svg +17 -0
- package/apps/web/src/app/agents/[slug]/page.tsx +2235 -0
- package/apps/web/src/app/agents/new/page.tsx +1161 -0
- package/apps/web/src/app/api/agents/[id]/access/route.ts +76 -0
- package/apps/web/src/app/api/agents/[id]/claude-md/route.ts +111 -0
- package/apps/web/src/app/api/agents/[id]/logs/route.ts +84 -0
- package/apps/web/src/app/api/agents/[id]/manifest/route.ts +32 -0
- package/apps/web/src/app/api/agents/[id]/mcps/route.ts +73 -0
- package/apps/web/src/app/api/agents/[id]/memories/[memId]/route.ts +31 -0
- package/apps/web/src/app/api/agents/[id]/memories/route.ts +56 -0
- package/apps/web/src/app/api/agents/[id]/permissions/route.ts +74 -0
- package/apps/web/src/app/api/agents/[id]/reload/route.ts +33 -0
- package/apps/web/src/app/api/agents/[id]/restrictions/route.ts +85 -0
- package/apps/web/src/app/api/agents/[id]/route.ts +81 -0
- package/apps/web/src/app/api/agents/[id]/skills/[skillId]/route.ts +52 -0
- package/apps/web/src/app/api/agents/[id]/skills/route.ts +80 -0
- package/apps/web/src/app/api/agents/[id]/slack-info/route.ts +38 -0
- package/apps/web/src/app/api/agents/[id]/snapshots/[sid]/restore/route.ts +61 -0
- package/apps/web/src/app/api/agents/[id]/snapshots/[sid]/route.ts +53 -0
- package/apps/web/src/app/api/agents/[id]/snapshots/route.ts +84 -0
- package/apps/web/src/app/api/agents/[id]/start/route.ts +35 -0
- package/apps/web/src/app/api/agents/[id]/stop/route.ts +35 -0
- package/apps/web/src/app/api/agents/route.ts +99 -0
- package/apps/web/src/app/api/auth/login/route.ts +39 -0
- package/apps/web/src/app/api/auth/logout/route.ts +21 -0
- package/apps/web/src/app/api/auth/me/route.ts +24 -0
- package/apps/web/src/app/api/auth/users/[id]/route.ts +48 -0
- package/apps/web/src/app/api/auth/users/route.ts +63 -0
- package/apps/web/src/app/api/env-vars/[key]/route.ts +66 -0
- package/apps/web/src/app/api/env-vars/route.ts +59 -0
- package/apps/web/src/app/api/jobs/[id]/route.ts +51 -0
- package/apps/web/src/app/api/jobs/[id]/runs/route.ts +24 -0
- package/apps/web/src/app/api/jobs/route.ts +42 -0
- package/apps/web/src/app/api/mcps/[id]/route.ts +60 -0
- package/apps/web/src/app/api/mcps/[id]/test/route.ts +195 -0
- package/apps/web/src/app/api/mcps/route.ts +72 -0
- package/apps/web/src/app/api/settings/route.ts +42 -0
- package/apps/web/src/app/globals.css +124 -0
- package/apps/web/src/app/icon.svg +17 -0
- package/apps/web/src/app/jobs/page.tsx +543 -0
- package/apps/web/src/app/layout-shell.tsx +89 -0
- package/apps/web/src/app/layout.tsx +18 -0
- package/apps/web/src/app/login/layout.tsx +9 -0
- package/apps/web/src/app/login/page.tsx +150 -0
- package/apps/web/src/app/page.tsx +573 -0
- package/apps/web/src/app/settings/env-vars/page.tsx +216 -0
- package/apps/web/src/app/settings/mcps/page.tsx +763 -0
- package/apps/web/src/app/settings/page.tsx +528 -0
- package/apps/web/src/app/sidebar.tsx +345 -0
- package/apps/web/src/lib/__tests__/api-guard.test.ts +189 -0
- package/apps/web/src/lib/__tests__/auth.test.ts +262 -0
- package/apps/web/src/lib/__tests__/boss-registry.test.ts +323 -0
- package/apps/web/src/lib/__tests__/compile.test.ts +161 -0
- package/apps/web/src/lib/__tests__/db-agent-hierarchy.test.ts +136 -0
- package/apps/web/src/lib/__tests__/db-env-vars.test.ts +216 -0
- package/apps/web/src/lib/__tests__/db-restrictions.test.ts +117 -0
- package/apps/web/src/lib/__tests__/db.integration.test.ts +271 -0
- package/apps/web/src/lib/__tests__/diff.test.ts +102 -0
- package/apps/web/src/lib/__tests__/mcp-mask.test.ts +274 -0
- package/apps/web/src/lib/__tests__/skill-templates.test.ts +237 -0
- package/apps/web/src/lib/__tests__/slack-manifest.test.ts +105 -0
- package/apps/web/src/lib/api-guard.ts +68 -0
- package/apps/web/src/lib/auth-context.tsx +71 -0
- package/apps/web/src/lib/auth.ts +128 -0
- package/apps/web/src/lib/boss-registry.ts +90 -0
- package/apps/web/src/lib/compile.ts +51 -0
- package/apps/web/src/lib/db.ts +1196 -0
- package/apps/web/src/lib/diff.ts +43 -0
- package/apps/web/src/lib/mcp-mask.ts +91 -0
- package/apps/web/src/lib/portal.tsx +23 -0
- package/apps/web/src/lib/skill-templates.ts +148 -0
- package/apps/web/src/lib/slack-manifest.ts +85 -0
- package/apps/web/src/middleware.ts +68 -0
- package/apps/web/tailwind.config.js +6 -0
- package/apps/web/tsconfig.json +23 -0
- package/apps/web/vitest.config.mts +21 -0
- package/cli/.claude/settings.local.json +6 -0
- package/cli/README.md +281 -0
- package/cli/node_modules/.package-lock.json +427 -0
- package/cli/node_modules/commander/LICENSE +22 -0
- package/cli/node_modules/commander/Readme.md +1157 -0
- package/cli/node_modules/commander/esm.mjs +16 -0
- package/cli/node_modules/commander/index.js +24 -0
- package/cli/node_modules/commander/lib/argument.js +149 -0
- package/cli/node_modules/commander/lib/command.js +2509 -0
- package/cli/node_modules/commander/lib/error.js +39 -0
- package/cli/node_modules/commander/lib/help.js +520 -0
- package/cli/node_modules/commander/lib/option.js +330 -0
- package/cli/node_modules/commander/lib/suggestSimilar.js +101 -0
- package/cli/node_modules/commander/package-support.json +16 -0
- package/cli/node_modules/commander/package.json +84 -0
- package/cli/node_modules/commander/typings/esm.d.mts +3 -0
- package/cli/node_modules/commander/typings/index.d.ts +969 -0
- package/cli/package-lock.json +449 -0
- package/cli/package.json +44 -0
- package/cli/src/commands/init.ts +514 -0
- package/cli/src/commands/manage.ts +115 -0
- package/cli/src/index.ts +63 -0
- package/cli/tsconfig.json +14 -0
- package/docker-compose.yml +122 -0
- package/docs/agents/boss-agents.mdx +108 -0
- package/docs/agents/creating-agents.mdx +132 -0
- package/docs/agents/memory.mdx +113 -0
- package/docs/agents/tools.mdx +103 -0
- package/docs/configuration/env-vars.mdx +166 -0
- package/docs/configuration/mcp-servers.mdx +203 -0
- package/docs/configuration/slack-app.mdx +175 -0
- package/docs/docs.json +79 -0
- package/docs/favicon.svg +17 -0
- package/docs/features/history.mdx +60 -0
- package/docs/features/import-export.mdx +77 -0
- package/docs/features/logs.mdx +131 -0
- package/docs/features/multi-workspace.mdx +90 -0
- package/docs/features/scheduled-jobs.mdx +231 -0
- package/docs/features/users.mdx +92 -0
- package/docs/introduction.mdx +160 -0
- package/docs/logo/dark.svg +17 -0
- package/docs/logo/light.svg +17 -0
- package/docs/logo/wide-dark.svg +12 -0
- package/docs/logo/wide-light.svg +12 -0
- package/docs/quickstart.mdx +270 -0
- package/docs/self-hosting/docker.mdx +151 -0
- package/docs/self-hosting/production.mdx +176 -0
- package/package.json +20 -36
- package/packages/shared/dist/index.d.ts +8 -0
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +24 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/shared/dist/types.d.ts +584 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/types.js +39 -0
- package/packages/shared/dist/types.js.map +1 -0
- package/packages/shared/package.json +15 -0
- package/packages/shared/src/db/schema.sql +354 -0
- package/packages/shared/src/index.ts +8 -0
- package/packages/shared/src/types.ts +683 -0
- package/packages/shared/tsconfig.json +17 -0
- package/scripts/dev.sh +45 -0
- /package/{dist → cli/dist}/commands/init.d.ts +0 -0
- /package/{dist → cli/dist}/commands/init.js +0 -0
- /package/{dist → cli/dist}/commands/manage.d.ts +0 -0
- /package/{dist → cli/dist}/commands/manage.js +0 -0
- /package/{dist → cli/dist}/index.d.ts +0 -0
- /package/{dist → cli/dist}/index.js +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Agent write-access management API.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/[id]/access — List users with explicit write access
|
|
5
|
+
* POST /api/agents/[id]/access — Grant write access to a user
|
|
6
|
+
* DELETE /api/agents/[id]/access — Revoke write access from a user
|
|
7
|
+
*
|
|
8
|
+
* @module web/api/agents/[id]/access
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
12
|
+
import { guardAdmin } from '@/lib/api-guard';
|
|
13
|
+
import { getAgentWriteUsers, grantAgentWrite, revokeAgentWrite, getAllUsers, userCanWriteAgent } from '@/lib/db';
|
|
14
|
+
import { getSessionFromRequest } from '@/lib/auth';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/agents/[id]/access
|
|
18
|
+
* - For admins: returns write-grant list + all users for the assignment UI.
|
|
19
|
+
* - For editors/viewers: returns { canWrite: bool } for the current session user.
|
|
20
|
+
*/
|
|
21
|
+
export async function GET(
|
|
22
|
+
req: NextRequest,
|
|
23
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
24
|
+
): Promise<NextResponse> {
|
|
25
|
+
const { id } = await params;
|
|
26
|
+
const session = getSessionFromRequest(req);
|
|
27
|
+
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
28
|
+
|
|
29
|
+
if (session.role === 'admin' || session.role === 'superadmin') {
|
|
30
|
+
const [writeUsers, allUsers] = await Promise.all([
|
|
31
|
+
getAgentWriteUsers(id),
|
|
32
|
+
getAllUsers(),
|
|
33
|
+
]);
|
|
34
|
+
return NextResponse.json({ writeUsers, allUsers: allUsers.map(u => ({ id: u.id, username: u.username, role: u.role })) });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// For editors/viewers — just return their own write permission
|
|
38
|
+
const canWrite = await userCanWriteAgent(id, session.username, session.role);
|
|
39
|
+
return NextResponse.json({ canWrite });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* POST /api/agents/[id]/access
|
|
44
|
+
* Grants write access to a user (admin only).
|
|
45
|
+
* Body: { userId: string }
|
|
46
|
+
*/
|
|
47
|
+
export async function POST(
|
|
48
|
+
req: NextRequest,
|
|
49
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
50
|
+
): Promise<NextResponse> {
|
|
51
|
+
const denied = guardAdmin(req);
|
|
52
|
+
if (denied) return denied;
|
|
53
|
+
const { id } = await params;
|
|
54
|
+
const { userId } = await req.json().catch(() => ({}));
|
|
55
|
+
if (!userId) return NextResponse.json({ error: 'userId required' }, { status: 400 });
|
|
56
|
+
await grantAgentWrite(id, userId);
|
|
57
|
+
return new NextResponse(null, { status: 204 });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* DELETE /api/agents/[id]/access
|
|
62
|
+
* Revokes write access from a user (admin only).
|
|
63
|
+
* Body: { userId: string }
|
|
64
|
+
*/
|
|
65
|
+
export async function DELETE(
|
|
66
|
+
req: NextRequest,
|
|
67
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
68
|
+
): Promise<NextResponse> {
|
|
69
|
+
const denied = guardAdmin(req);
|
|
70
|
+
if (denied) return denied;
|
|
71
|
+
const { id } = await params;
|
|
72
|
+
const { userId } = await req.json().catch(() => ({}));
|
|
73
|
+
if (!userId) return NextResponse.json({ error: 'userId required' }, { status: 400 });
|
|
74
|
+
await revokeAgentWrite(id, userId);
|
|
75
|
+
return new NextResponse(null, { status: 204 });
|
|
76
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST API routes for an agent's CLAUDE.md instruction file.
|
|
3
|
+
*
|
|
4
|
+
* CLAUDE.md is the agent's main identity/instruction file, stored as
|
|
5
|
+
* agents.claude_md in the database. It is separate from skills — skills
|
|
6
|
+
* are Claude Code slash commands written to .claude/commands/ at runtime.
|
|
7
|
+
*
|
|
8
|
+
* GET /api/agents/[id]/claude-md — Returns the stored CLAUDE.md content
|
|
9
|
+
* with memories appended (read-only view).
|
|
10
|
+
* PUT /api/agents/[id]/claude-md — Updates agents.claude_md directly.
|
|
11
|
+
*
|
|
12
|
+
* @module web/api/agents/[id]/claude-md
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
16
|
+
import { getAgentById, getAgentMemories, updateAgentClaudeMd, publishAgentEvent, getAgentSkills, getAgentPermissions, getAgentMcpServers, createSnapshot } from '@/lib/db';
|
|
17
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
18
|
+
import { getSessionFromRequest } from '@/lib/auth';
|
|
19
|
+
import { skillToSnapshotSkill } from '@/lib/compile';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* GET /api/agents/[id]/claude-md
|
|
23
|
+
* Returns the agent's CLAUDE.md content with memories appended.
|
|
24
|
+
*
|
|
25
|
+
* @param {NextRequest} _req
|
|
26
|
+
* @param {{ params: Promise<{ id: string }> }} ctx
|
|
27
|
+
* @returns {Promise<NextResponse>} Plain-text CLAUDE.md or 404.
|
|
28
|
+
*/
|
|
29
|
+
export async function GET(
|
|
30
|
+
_req: NextRequest,
|
|
31
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
32
|
+
) {
|
|
33
|
+
const { id } = await params;
|
|
34
|
+
const agent = await getAgentById(id);
|
|
35
|
+
if (!agent) return new NextResponse('Not found', { status: 404 });
|
|
36
|
+
|
|
37
|
+
const memories = await getAgentMemories(id);
|
|
38
|
+
|
|
39
|
+
const sections: string[] = [];
|
|
40
|
+
|
|
41
|
+
if (agent.claudeMd.trim()) {
|
|
42
|
+
sections.push(agent.claudeMd.trim());
|
|
43
|
+
} else {
|
|
44
|
+
// Fallback: minimal identity block if claude_md not yet set
|
|
45
|
+
const lines = [`# ${agent.name}`];
|
|
46
|
+
if (agent.persona) lines.push('', agent.persona);
|
|
47
|
+
if (agent.description) lines.push('', agent.description);
|
|
48
|
+
sections.push(lines.join('\n'));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (memories.length > 0) {
|
|
52
|
+
const order = ['feedback', 'user', 'project', 'reference'];
|
|
53
|
+
const grouped = memories.reduce<Record<string, typeof memories>>((acc, m) => {
|
|
54
|
+
(acc[m.type] ??= []).push(m);
|
|
55
|
+
return acc;
|
|
56
|
+
}, {});
|
|
57
|
+
const memParts = order
|
|
58
|
+
.filter(t => grouped[t]?.length)
|
|
59
|
+
.map(t => `## ${t.charAt(0).toUpperCase() + t.slice(1)} Memories\n\n` +
|
|
60
|
+
grouped[t].map(m => `### ${m.name}\n${m.content}`).join('\n\n'));
|
|
61
|
+
sections.push(`# Agent Memory\n\n${memParts.join('\n\n')}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return new NextResponse(sections.join('\n\n'), {
|
|
65
|
+
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* PUT /api/agents/[id]/claude-md
|
|
71
|
+
* Saves the CLAUDE.md content to agents.claude_md.
|
|
72
|
+
* Does NOT touch skills — skills are managed separately via /api/agents/[id]/skills.
|
|
73
|
+
* Body: raw text/plain content.
|
|
74
|
+
*
|
|
75
|
+
* @param {NextRequest} req
|
|
76
|
+
* @param {{ params: Promise<{ id: string }> }} ctx
|
|
77
|
+
* @returns {Promise<NextResponse>} 204 No Content or error.
|
|
78
|
+
*/
|
|
79
|
+
export async function PUT(
|
|
80
|
+
req: NextRequest,
|
|
81
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
82
|
+
) {
|
|
83
|
+
const { id } = await params;
|
|
84
|
+
const denied = await guardAgentWrite(req, id);
|
|
85
|
+
if (denied) return denied;
|
|
86
|
+
const agent = await getAgentById(id);
|
|
87
|
+
if (!agent) return new NextResponse('Not found', { status: 404 });
|
|
88
|
+
|
|
89
|
+
const content = await req.text();
|
|
90
|
+
if (!content.trim()) return new NextResponse('Empty content', { status: 400 });
|
|
91
|
+
|
|
92
|
+
// Snapshot current state before overwriting
|
|
93
|
+
const session = getSessionFromRequest(req);
|
|
94
|
+
const [currentSkills, currentPerms, currentMcps] = await Promise.all([
|
|
95
|
+
getAgentSkills(id),
|
|
96
|
+
getAgentPermissions(id),
|
|
97
|
+
getAgentMcpServers(id),
|
|
98
|
+
]);
|
|
99
|
+
await createSnapshot(
|
|
100
|
+
id, 'claude-md', session?.username ?? 'system', null,
|
|
101
|
+
currentSkills.map(skillToSnapshotSkill),
|
|
102
|
+
currentPerms?.allowedTools ?? [],
|
|
103
|
+
currentPerms?.deniedTools ?? [],
|
|
104
|
+
currentMcps.map(m => m.id),
|
|
105
|
+
agent.claudeMd,
|
|
106
|
+
).catch(() => {});
|
|
107
|
+
|
|
108
|
+
await updateAgentClaudeMd(id, content);
|
|
109
|
+
await publishAgentEvent({ type: 'reload', agentId: id });
|
|
110
|
+
return new NextResponse(null, { status: 204 });
|
|
111
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview GET /api/agents/[id]/logs
|
|
3
|
+
* Server-Sent Events (SSE) stream of live runner logs for a specific agent.
|
|
4
|
+
* Reads from the runner container's stdout via Docker logs API.
|
|
5
|
+
*
|
|
6
|
+
* NOTE: In Docker Compose, this uses `docker logs --follow --tail=100 <runner>`.
|
|
7
|
+
* The runner prefixes each log line with `[agentSlug]` so we filter by agent.
|
|
8
|
+
*
|
|
9
|
+
* @module web/api/agents/[id]/logs
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { NextRequest } from 'next/server';
|
|
13
|
+
import { getAgentById } from '@/lib/db';
|
|
14
|
+
import { spawn } from 'child_process';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/agents/[id]/logs
|
|
18
|
+
* Returns an SSE stream of filtered log lines for the agent.
|
|
19
|
+
*
|
|
20
|
+
* @param {NextRequest} _req
|
|
21
|
+
* @param {{ params: Promise<{ id: string }> }} ctx
|
|
22
|
+
* @returns {Response} SSE stream.
|
|
23
|
+
*/
|
|
24
|
+
export async function GET(
|
|
25
|
+
_req: NextRequest,
|
|
26
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
27
|
+
): Promise<Response> {
|
|
28
|
+
const { id } = await params;
|
|
29
|
+
const agent = await getAgentById(id).catch(() => null);
|
|
30
|
+
const slug = agent?.slug ?? id;
|
|
31
|
+
|
|
32
|
+
const encoder = new TextEncoder();
|
|
33
|
+
|
|
34
|
+
const stream = new ReadableStream({
|
|
35
|
+
start(controller) {
|
|
36
|
+
// Tail the runner container logs, filtering for lines containing [slug]
|
|
37
|
+
const proc = spawn('docker', [
|
|
38
|
+
'logs', '--follow', '--tail=200',
|
|
39
|
+
'slackhive-runner-1',
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
function send(line: string) {
|
|
43
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(line)}\n\n`));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let buffer = '';
|
|
47
|
+
proc.stdout.on('data', (chunk: Buffer) => {
|
|
48
|
+
buffer += chunk.toString();
|
|
49
|
+
const lines = buffer.split('\n');
|
|
50
|
+
buffer = lines.pop() ?? '';
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (line.includes(`"agent":"${slug}"`)) send(line);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
proc.stderr.on('data', (chunk: Buffer) => {
|
|
57
|
+
buffer += chunk.toString();
|
|
58
|
+
const lines = buffer.split('\n');
|
|
59
|
+
buffer = lines.pop() ?? '';
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
if (line.includes(`"agent":"${slug}"`)) send(line);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
proc.on('close', () => {
|
|
66
|
+
try { controller.close(); } catch { /* already closed */ }
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Clean up if client disconnects
|
|
70
|
+
_req.signal.addEventListener('abort', () => {
|
|
71
|
+
proc.kill();
|
|
72
|
+
try { controller.close(); } catch { /* already closed */ }
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return new Response(stream, {
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'text/event-stream',
|
|
80
|
+
'Cache-Control': 'no-cache',
|
|
81
|
+
'Connection': 'keep-alive',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview GET /api/agents/[id]/manifest
|
|
3
|
+
* Returns a generated Slack app manifest JSON for the agent onboarding wizard.
|
|
4
|
+
* Paste the output into api.slack.com/apps → Create from Manifest.
|
|
5
|
+
*
|
|
6
|
+
* @module web/api/agents/[id]/manifest
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
10
|
+
import { getAgentById } from '@/lib/db';
|
|
11
|
+
import { generateSlackManifest } from '@/lib/slack-manifest';
|
|
12
|
+
|
|
13
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* GET /api/agents/[id]/manifest
|
|
17
|
+
*
|
|
18
|
+
* @param {NextRequest} _req
|
|
19
|
+
* @param {RouteParams} ctx
|
|
20
|
+
* @returns {Promise<NextResponse>} SlackAppManifest JSON or error.
|
|
21
|
+
*/
|
|
22
|
+
export async function GET(_req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
23
|
+
try {
|
|
24
|
+
const { id } = await params;
|
|
25
|
+
const agent = await getAgentById(id);
|
|
26
|
+
if (!agent) return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
27
|
+
const manifest = generateSlackManifest({ name: agent.name, description: agent.description, isBoss: agent.isBoss });
|
|
28
|
+
return NextResponse.json(manifest);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST API routes for agent MCP assignments.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/[id]/mcps — List MCPs assigned to this agent
|
|
5
|
+
* PUT /api/agents/[id]/mcps — Replace all MCP assignments, then trigger reload
|
|
6
|
+
*
|
|
7
|
+
* @module web/api/agents/[id]/mcps
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
+
import { getAgentById, getAgentSkills, getAgentPermissions, getAgentMcpServers, setAgentMcps, publishAgentEvent, createSnapshot } from '@/lib/db';
|
|
12
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
13
|
+
import { getSessionFromRequest } from '@/lib/auth';
|
|
14
|
+
import { skillToSnapshotSkill } from '@/lib/compile';
|
|
15
|
+
|
|
16
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* GET /api/agents/[id]/mcps
|
|
20
|
+
*
|
|
21
|
+
* @param {NextRequest} _req
|
|
22
|
+
* @param {RouteParams} ctx
|
|
23
|
+
* @returns {Promise<NextResponse>} JSON array of assigned McpServer objects.
|
|
24
|
+
*/
|
|
25
|
+
export async function GET(_req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
26
|
+
try {
|
|
27
|
+
const { id } = await params;
|
|
28
|
+
const mcps = await getAgentMcpServers(id);
|
|
29
|
+
return NextResponse.json(mcps);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* PUT /api/agents/[id]/mcps
|
|
37
|
+
* Replaces all MCP assignments for an agent and triggers a reload.
|
|
38
|
+
*
|
|
39
|
+
* @param {NextRequest} req - Body: { mcpIds: string[] }
|
|
40
|
+
* @param {RouteParams} ctx
|
|
41
|
+
* @returns {Promise<NextResponse>} 200 ok or error.
|
|
42
|
+
*/
|
|
43
|
+
export async function PUT(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
44
|
+
try {
|
|
45
|
+
const { id } = await params;
|
|
46
|
+
const denied = await guardAgentWrite(req, id);
|
|
47
|
+
if (denied) return denied;
|
|
48
|
+
const { mcpIds } = (await req.json()) as { mcpIds: string[] };
|
|
49
|
+
|
|
50
|
+
// Snapshot before mutation
|
|
51
|
+
const session = getSessionFromRequest(req);
|
|
52
|
+
const [agent, currentSkills, perms, currentMcps] = await Promise.all([
|
|
53
|
+
getAgentById(id),
|
|
54
|
+
getAgentSkills(id),
|
|
55
|
+
getAgentPermissions(id),
|
|
56
|
+
getAgentMcpServers(id),
|
|
57
|
+
]);
|
|
58
|
+
await createSnapshot(
|
|
59
|
+
id, 'mcps', session?.username ?? 'system', null,
|
|
60
|
+
currentSkills.map(skillToSnapshotSkill),
|
|
61
|
+
perms?.allowedTools ?? [],
|
|
62
|
+
perms?.deniedTools ?? [],
|
|
63
|
+
currentMcps.map(m => m.id),
|
|
64
|
+
agent?.claudeMd ?? '',
|
|
65
|
+
).catch(() => {});
|
|
66
|
+
|
|
67
|
+
await setAgentMcps(id, mcpIds ?? []);
|
|
68
|
+
await publishAgentEvent({ type: 'reload', agentId: id });
|
|
69
|
+
return NextResponse.json({ ok: true });
|
|
70
|
+
} catch (err) {
|
|
71
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview DELETE /api/agents/[id]/memories/[memId]
|
|
3
|
+
* Removes a single memory entry for an agent.
|
|
4
|
+
*
|
|
5
|
+
* @module web/api/agents/[id]/memories/[memId]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
9
|
+
import { deleteMemory } from '@/lib/db';
|
|
10
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
11
|
+
|
|
12
|
+
type RouteParams = { params: Promise<{ id: string; memId: string }> };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* DELETE /api/agents/[id]/memories/[memId]
|
|
16
|
+
*
|
|
17
|
+
* @param {NextRequest} _req
|
|
18
|
+
* @param {RouteParams} ctx
|
|
19
|
+
* @returns {Promise<NextResponse>} 204 No Content or error.
|
|
20
|
+
*/
|
|
21
|
+
export async function DELETE(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
22
|
+
try {
|
|
23
|
+
const { id, memId } = await params;
|
|
24
|
+
const denied = await guardAgentWrite(req, id);
|
|
25
|
+
if (denied) return denied;
|
|
26
|
+
await deleteMemory(memId);
|
|
27
|
+
return new NextResponse(null, { status: 204 });
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST API routes for agent memories.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/[id]/memories — List all memories for an agent
|
|
5
|
+
* POST /api/agents/[id]/memories — Create or update a memory entry
|
|
6
|
+
*
|
|
7
|
+
* @module web/api/agents/[id]/memories
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
+
import { getAgentMemories, upsertMemory } from '@/lib/db';
|
|
12
|
+
import type { UpsertMemoryRequest } from '@slackhive/shared';
|
|
13
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
14
|
+
|
|
15
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* GET /api/agents/[id]/memories
|
|
19
|
+
*
|
|
20
|
+
* @param {NextRequest} _req
|
|
21
|
+
* @param {RouteParams} ctx
|
|
22
|
+
* @returns {Promise<NextResponse>} JSON array of Memory objects.
|
|
23
|
+
*/
|
|
24
|
+
export async function GET(_req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
25
|
+
try {
|
|
26
|
+
const { id } = await params;
|
|
27
|
+
const memories = await getAgentMemories(id);
|
|
28
|
+
return NextResponse.json(memories);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* POST /api/agents/[id]/memories
|
|
36
|
+
* Creates or updates a memory entry.
|
|
37
|
+
*
|
|
38
|
+
* @param {NextRequest} req - Body: UpsertMemoryRequest
|
|
39
|
+
* @param {RouteParams} ctx
|
|
40
|
+
* @returns {Promise<NextResponse>} The upserted Memory or error.
|
|
41
|
+
*/
|
|
42
|
+
export async function POST(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
43
|
+
try {
|
|
44
|
+
const { id } = await params;
|
|
45
|
+
const denied = await guardAgentWrite(req, id);
|
|
46
|
+
if (denied) return denied;
|
|
47
|
+
const body = (await req.json()) as UpsertMemoryRequest;
|
|
48
|
+
if (!body.type || !body.name || !body.content) {
|
|
49
|
+
return NextResponse.json({ error: 'type, name, content are required' }, { status: 400 });
|
|
50
|
+
}
|
|
51
|
+
const memory = await upsertMemory(id, body.type, body.name, body.content);
|
|
52
|
+
return NextResponse.json(memory, { status: 201 });
|
|
53
|
+
} catch (err) {
|
|
54
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST API routes for agent tool permissions.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/[id]/permissions — Get current permissions
|
|
5
|
+
* PUT /api/agents/[id]/permissions — Replace permissions, then trigger reload
|
|
6
|
+
*
|
|
7
|
+
* @module web/api/agents/[id]/permissions
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
+
import { getAgentById, getAgentSkills, getAgentPermissions, getAgentMcpServers, upsertPermissions, publishAgentEvent, createSnapshot } from '@/lib/db';
|
|
12
|
+
import type { UpdatePermissionsRequest } from '@slackhive/shared';
|
|
13
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
14
|
+
import { getSessionFromRequest } from '@/lib/auth';
|
|
15
|
+
import { skillToSnapshotSkill } from '@/lib/compile';
|
|
16
|
+
|
|
17
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* GET /api/agents/[id]/permissions
|
|
21
|
+
*
|
|
22
|
+
* @param {NextRequest} _req
|
|
23
|
+
* @param {RouteParams} ctx
|
|
24
|
+
* @returns {Promise<NextResponse>} Permission object or null.
|
|
25
|
+
*/
|
|
26
|
+
export async function GET(_req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
27
|
+
try {
|
|
28
|
+
const { id } = await params;
|
|
29
|
+
const perms = await getAgentPermissions(id);
|
|
30
|
+
return NextResponse.json(perms ?? { allowedTools: [], deniedTools: [] });
|
|
31
|
+
} catch (err) {
|
|
32
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* PUT /api/agents/[id]/permissions
|
|
38
|
+
* Replaces all tool permissions for an agent.
|
|
39
|
+
*
|
|
40
|
+
* @param {NextRequest} req - Body: { allowedTools: string[], deniedTools: string[] }
|
|
41
|
+
* @param {RouteParams} ctx
|
|
42
|
+
* @returns {Promise<NextResponse>} 200 ok or error.
|
|
43
|
+
*/
|
|
44
|
+
export async function PUT(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
45
|
+
try {
|
|
46
|
+
const { id } = await params;
|
|
47
|
+
const denied = await guardAgentWrite(req, id);
|
|
48
|
+
if (denied) return denied;
|
|
49
|
+
const body = (await req.json()) as UpdatePermissionsRequest;
|
|
50
|
+
|
|
51
|
+
// Snapshot before mutation
|
|
52
|
+
const session = getSessionFromRequest(req);
|
|
53
|
+
const [agent, currentSkills, perms, mcps] = await Promise.all([
|
|
54
|
+
getAgentById(id),
|
|
55
|
+
getAgentSkills(id),
|
|
56
|
+
getAgentPermissions(id),
|
|
57
|
+
getAgentMcpServers(id),
|
|
58
|
+
]);
|
|
59
|
+
await createSnapshot(
|
|
60
|
+
id, 'permissions', session?.username ?? 'system', null,
|
|
61
|
+
currentSkills.map(skillToSnapshotSkill),
|
|
62
|
+
perms?.allowedTools ?? [],
|
|
63
|
+
perms?.deniedTools ?? [],
|
|
64
|
+
mcps.map(m => m.id),
|
|
65
|
+
agent?.claudeMd ?? '',
|
|
66
|
+
).catch(() => {});
|
|
67
|
+
|
|
68
|
+
await upsertPermissions(id, body.allowedTools ?? [], body.deniedTools ?? []);
|
|
69
|
+
await publishAgentEvent({ type: 'reload', agentId: id });
|
|
70
|
+
return NextResponse.json({ ok: true });
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview POST /api/agents/[id]/reload
|
|
3
|
+
* Publishes a reload event: runner stops the agent, recompiles CLAUDE.md, and restarts it.
|
|
4
|
+
*
|
|
5
|
+
* @module web/api/agents/[id]/reload
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
9
|
+
import { getAgentById, publishAgentEvent } from '@/lib/db';
|
|
10
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
11
|
+
|
|
12
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* POST /api/agents/[id]/reload
|
|
16
|
+
*
|
|
17
|
+
* @param {NextRequest} _req
|
|
18
|
+
* @param {RouteParams} ctx
|
|
19
|
+
* @returns {Promise<NextResponse>} 200 on success, 404 or 500 on error.
|
|
20
|
+
*/
|
|
21
|
+
export async function POST(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
22
|
+
try {
|
|
23
|
+
const { id } = await params;
|
|
24
|
+
const denied = await guardAgentWrite(req, id);
|
|
25
|
+
if (denied) return denied;
|
|
26
|
+
const agent = await getAgentById(id);
|
|
27
|
+
if (!agent) return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
28
|
+
await publishAgentEvent({ type: 'reload', agentId: id });
|
|
29
|
+
return NextResponse.json({ ok: true });
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview REST API routes for per-agent channel restrictions.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/agents/[id]/restrictions — Get current restrictions
|
|
5
|
+
* PUT /api/agents/[id]/restrictions — Replace restrictions, then trigger reload
|
|
6
|
+
*
|
|
7
|
+
* @module web/api/agents/[id]/restrictions
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
+
import {
|
|
12
|
+
getAgentById,
|
|
13
|
+
getAgentSkills,
|
|
14
|
+
getAgentPermissions,
|
|
15
|
+
getAgentMcpServers,
|
|
16
|
+
getAgentRestrictions,
|
|
17
|
+
upsertRestrictions,
|
|
18
|
+
publishAgentEvent,
|
|
19
|
+
createSnapshot,
|
|
20
|
+
} from '@/lib/db';
|
|
21
|
+
import type { UpdateRestrictionsRequest } from '@slackhive/shared';
|
|
22
|
+
import { guardAgentWrite } from '@/lib/api-guard';
|
|
23
|
+
import { getSessionFromRequest } from '@/lib/auth';
|
|
24
|
+
import { skillToSnapshotSkill } from '@/lib/compile';
|
|
25
|
+
|
|
26
|
+
type RouteParams = { params: Promise<{ id: string }> };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* GET /api/agents/[id]/restrictions
|
|
30
|
+
*
|
|
31
|
+
* @param {NextRequest} _req
|
|
32
|
+
* @param {RouteParams} ctx
|
|
33
|
+
* @returns {Promise<NextResponse>} Restriction object or empty default.
|
|
34
|
+
*/
|
|
35
|
+
export async function GET(_req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
36
|
+
try {
|
|
37
|
+
const { id } = await params;
|
|
38
|
+
const restrictions = await getAgentRestrictions(id);
|
|
39
|
+
return NextResponse.json(restrictions ?? { allowedChannels: [] });
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* PUT /api/agents/[id]/restrictions
|
|
47
|
+
* Replaces channel restrictions for an agent.
|
|
48
|
+
*
|
|
49
|
+
* @param {NextRequest} req - Body: { allowedChannels: string[] }
|
|
50
|
+
* @param {RouteParams} ctx
|
|
51
|
+
* @returns {Promise<NextResponse>} 200 ok or error.
|
|
52
|
+
*/
|
|
53
|
+
export async function PUT(req: NextRequest, { params }: RouteParams): Promise<NextResponse> {
|
|
54
|
+
try {
|
|
55
|
+
const { id } = await params;
|
|
56
|
+
const denied = await guardAgentWrite(req, id);
|
|
57
|
+
if (denied) return denied;
|
|
58
|
+
const body = (await req.json()) as UpdateRestrictionsRequest;
|
|
59
|
+
|
|
60
|
+
// Snapshot before mutation
|
|
61
|
+
const session = getSessionFromRequest(req);
|
|
62
|
+
const [agent, currentSkills, perms, mcps, currentRestrictions] = await Promise.all([
|
|
63
|
+
getAgentById(id),
|
|
64
|
+
getAgentSkills(id),
|
|
65
|
+
getAgentPermissions(id),
|
|
66
|
+
getAgentMcpServers(id),
|
|
67
|
+
getAgentRestrictions(id),
|
|
68
|
+
]);
|
|
69
|
+
await createSnapshot(
|
|
70
|
+
id, 'restrictions', session?.username ?? 'system', null,
|
|
71
|
+
currentSkills.map(skillToSnapshotSkill),
|
|
72
|
+
perms?.allowedTools ?? [],
|
|
73
|
+
perms?.deniedTools ?? [],
|
|
74
|
+
mcps.map(m => m.id),
|
|
75
|
+
agent?.claudeMd ?? '',
|
|
76
|
+
currentRestrictions?.allowedChannels ?? [],
|
|
77
|
+
).catch(() => {});
|
|
78
|
+
|
|
79
|
+
await upsertRestrictions(id, body.allowedChannels ?? []);
|
|
80
|
+
await publishAgentEvent({ type: 'reload', agentId: id });
|
|
81
|
+
return NextResponse.json({ ok: true });
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
|
|
84
|
+
}
|
|
85
|
+
}
|