slackhive 0.1.41 → 0.1.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (534) hide show
  1. package/cli/dist/index.js +15786 -52
  2. package/package.json +9 -3
  3. package/.dockerignore +0 -14
  4. package/.env.example +0 -44
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -65
  6. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -38
  8. package/.github/PULL_REQUEST_TEMPLATE.md +0 -27
  9. package/.github/dependabot.yml +0 -20
  10. package/.github/workflows/audit.yml +0 -149
  11. package/.github/workflows/ci.yml +0 -135
  12. package/CHANGELOG.md +0 -52
  13. package/CODE_OF_CONDUCT.md +0 -37
  14. package/CONTRIBUTING.md +0 -204
  15. package/SECURITY.md +0 -47
  16. package/apps/runner/Dockerfile +0 -33
  17. package/apps/runner/dist/__tests__/channel-restrictions.test.d.ts +0 -8
  18. package/apps/runner/dist/__tests__/channel-restrictions.test.js +0 -63
  19. package/apps/runner/dist/__tests__/channel-restrictions.test.js.map +0 -1
  20. package/apps/runner/dist/__tests__/claude-handler-resolve.test.d.ts +0 -20
  21. package/apps/runner/dist/__tests__/claude-handler-resolve.test.js +0 -178
  22. package/apps/runner/dist/__tests__/claude-handler-resolve.test.js.map +0 -1
  23. package/apps/runner/dist/__tests__/compile-claude-md.test.d.ts +0 -13
  24. package/apps/runner/dist/__tests__/compile-claude-md.test.js +0 -144
  25. package/apps/runner/dist/__tests__/compile-claude-md.test.js.map +0 -1
  26. package/apps/runner/dist/__tests__/memory-sync.test.d.ts +0 -11
  27. package/apps/runner/dist/__tests__/memory-sync.test.js +0 -56
  28. package/apps/runner/dist/__tests__/memory-sync.test.js.map +0 -1
  29. package/apps/runner/dist/__tests__/slack-file-support.test.d.ts +0 -9
  30. package/apps/runner/dist/__tests__/slack-file-support.test.js +0 -271
  31. package/apps/runner/dist/__tests__/slack-file-support.test.js.map +0 -1
  32. package/apps/runner/dist/__tests__/slack-formatting.test.d.ts +0 -12
  33. package/apps/runner/dist/__tests__/slack-formatting.test.js +0 -400
  34. package/apps/runner/dist/__tests__/slack-formatting.test.js.map +0 -1
  35. package/apps/runner/dist/__tests__/thread-context.test.d.ts +0 -12
  36. package/apps/runner/dist/__tests__/thread-context.test.js +0 -182
  37. package/apps/runner/dist/__tests__/thread-context.test.js.map +0 -1
  38. package/apps/runner/dist/agent-runner.d.ts +0 -118
  39. package/apps/runner/dist/agent-runner.js +0 -352
  40. package/apps/runner/dist/agent-runner.js.map +0 -1
  41. package/apps/runner/dist/claude-handler.d.ts +0 -122
  42. package/apps/runner/dist/claude-handler.js +0 -402
  43. package/apps/runner/dist/claude-handler.js.map +0 -1
  44. package/apps/runner/dist/compile-claude-md.d.ts +0 -59
  45. package/apps/runner/dist/compile-claude-md.js +0 -291
  46. package/apps/runner/dist/compile-claude-md.js.map +0 -1
  47. package/apps/runner/dist/correction-handler.d.ts +0 -46
  48. package/apps/runner/dist/correction-handler.js +0 -162
  49. package/apps/runner/dist/correction-handler.js.map +0 -1
  50. package/apps/runner/dist/correction-manager.d.ts +0 -53
  51. package/apps/runner/dist/correction-manager.js +0 -241
  52. package/apps/runner/dist/correction-manager.js.map +0 -1
  53. package/apps/runner/dist/db.d.ts +0 -193
  54. package/apps/runner/dist/db.js +0 -492
  55. package/apps/runner/dist/db.js.map +0 -1
  56. package/apps/runner/dist/index.d.ts +0 -9
  57. package/apps/runner/dist/index.js +0 -43
  58. package/apps/runner/dist/index.js.map +0 -1
  59. package/apps/runner/dist/job-scheduler.d.ts +0 -57
  60. package/apps/runner/dist/job-scheduler.js +0 -150
  61. package/apps/runner/dist/job-scheduler.js.map +0 -1
  62. package/apps/runner/dist/logger.d.ts +0 -32
  63. package/apps/runner/dist/logger.js +0 -52
  64. package/apps/runner/dist/logger.js.map +0 -1
  65. package/apps/runner/dist/mcp-process-manager.d.ts +0 -38
  66. package/apps/runner/dist/mcp-process-manager.js +0 -189
  67. package/apps/runner/dist/mcp-process-manager.js.map +0 -1
  68. package/apps/runner/dist/memory-mcp.d.ts +0 -14
  69. package/apps/runner/dist/memory-mcp.js +0 -88
  70. package/apps/runner/dist/memory-mcp.js.map +0 -1
  71. package/apps/runner/dist/memory-watcher.d.ts +0 -78
  72. package/apps/runner/dist/memory-watcher.js +0 -220
  73. package/apps/runner/dist/memory-watcher.js.map +0 -1
  74. package/apps/runner/dist/slack-handler.d.ts +0 -120
  75. package/apps/runner/dist/slack-handler.js +0 -843
  76. package/apps/runner/dist/slack-handler.js.map +0 -1
  77. package/apps/runner/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  78. package/apps/runner/package.json +0 -42
  79. package/apps/runner/src/__tests__/channel-restrictions.test.ts +0 -75
  80. package/apps/runner/src/__tests__/claude-handler-resolve.test.ts +0 -160
  81. package/apps/runner/src/__tests__/compile-claude-md.test.ts +0 -139
  82. package/apps/runner/src/__tests__/memory-sync.test.ts +0 -59
  83. package/apps/runner/src/__tests__/slack-file-support.test.ts +0 -376
  84. package/apps/runner/src/__tests__/slack-formatting.test.ts +0 -495
  85. package/apps/runner/src/__tests__/thread-context.test.ts +0 -215
  86. package/apps/runner/src/agent-runner.ts +0 -397
  87. package/apps/runner/src/claude-handler.ts +0 -475
  88. package/apps/runner/src/compile-claude-md.ts +0 -283
  89. package/apps/runner/src/correction-handler.ts +0 -191
  90. package/apps/runner/src/correction-manager.ts +0 -285
  91. package/apps/runner/src/db.ts +0 -604
  92. package/apps/runner/src/index.ts +0 -46
  93. package/apps/runner/src/job-scheduler.ts +0 -165
  94. package/apps/runner/src/logger.ts +0 -49
  95. package/apps/runner/src/mcp-process-manager.ts +0 -195
  96. package/apps/runner/src/memory-mcp.ts +0 -85
  97. package/apps/runner/src/memory-watcher.ts +0 -215
  98. package/apps/runner/src/slack-handler.ts +0 -929
  99. package/apps/runner/tsconfig.json +0 -17
  100. package/apps/runner/vitest.config.mts +0 -17
  101. package/apps/web/.eslintrc.json +0 -3
  102. package/apps/web/.next/app-build-manifest.json +0 -323
  103. package/apps/web/.next/app-path-routes-manifest.json +0 -46
  104. package/apps/web/.next/build-manifest.json +0 -33
  105. package/apps/web/.next/cache/.previewinfo +0 -1
  106. package/apps/web/.next/cache/.rscinfo +0 -1
  107. package/apps/web/.next/cache/webpack/client-production/0.pack +0 -0
  108. package/apps/web/.next/cache/webpack/client-production/1.pack +0 -0
  109. package/apps/web/.next/cache/webpack/client-production/2.pack +0 -0
  110. package/apps/web/.next/cache/webpack/client-production/3.pack +0 -0
  111. package/apps/web/.next/cache/webpack/client-production/4.pack +0 -0
  112. package/apps/web/.next/cache/webpack/client-production/index.pack +0 -0
  113. package/apps/web/.next/cache/webpack/client-production/index.pack.old +0 -0
  114. package/apps/web/.next/cache/webpack/edge-server-production/0.pack +0 -0
  115. package/apps/web/.next/cache/webpack/edge-server-production/1.pack +0 -0
  116. package/apps/web/.next/cache/webpack/edge-server-production/index.pack +0 -0
  117. package/apps/web/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
  118. package/apps/web/.next/cache/webpack/server-production/0.pack +0 -0
  119. package/apps/web/.next/cache/webpack/server-production/1.pack +0 -0
  120. package/apps/web/.next/cache/webpack/server-production/2.pack +0 -0
  121. package/apps/web/.next/cache/webpack/server-production/index.pack +0 -0
  122. package/apps/web/.next/cache/webpack/server-production/index.pack.old +0 -0
  123. package/apps/web/.next/diagnostics/build-diagnostics.json +0 -6
  124. package/apps/web/.next/diagnostics/framework.json +0 -1
  125. package/apps/web/.next/package.json +0 -1
  126. package/apps/web/.next/react-loadable-manifest.json +0 -1
  127. package/apps/web/.next/server/app/_not-found/page.js +0 -2
  128. package/apps/web/.next/server/app/_not-found/page.js.nft.json +0 -1
  129. package/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  130. package/apps/web/.next/server/app/agents/[slug]/page.js +0 -4
  131. package/apps/web/.next/server/app/agents/[slug]/page.js.nft.json +0 -1
  132. package/apps/web/.next/server/app/agents/[slug]/page_client-reference-manifest.js +0 -1
  133. package/apps/web/.next/server/app/agents/new/page.js +0 -2
  134. package/apps/web/.next/server/app/agents/new/page.js.nft.json +0 -1
  135. package/apps/web/.next/server/app/agents/new/page_client-reference-manifest.js +0 -1
  136. package/apps/web/.next/server/app/api/agents/[id]/access/route.js +0 -1
  137. package/apps/web/.next/server/app/api/agents/[id]/access/route.js.nft.json +0 -1
  138. package/apps/web/.next/server/app/api/agents/[id]/access/route_client-reference-manifest.js +0 -1
  139. package/apps/web/.next/server/app/api/agents/[id]/claude-md/route.js +0 -6
  140. package/apps/web/.next/server/app/api/agents/[id]/claude-md/route.js.nft.json +0 -1
  141. package/apps/web/.next/server/app/api/agents/[id]/claude-md/route_client-reference-manifest.js +0 -1
  142. package/apps/web/.next/server/app/api/agents/[id]/logs/route.js +0 -3
  143. package/apps/web/.next/server/app/api/agents/[id]/logs/route.js.nft.json +0 -1
  144. package/apps/web/.next/server/app/api/agents/[id]/logs/route_client-reference-manifest.js +0 -1
  145. package/apps/web/.next/server/app/api/agents/[id]/manifest/route.js +0 -1
  146. package/apps/web/.next/server/app/api/agents/[id]/manifest/route.js.nft.json +0 -1
  147. package/apps/web/.next/server/app/api/agents/[id]/manifest/route_client-reference-manifest.js +0 -1
  148. package/apps/web/.next/server/app/api/agents/[id]/mcps/route.js +0 -1
  149. package/apps/web/.next/server/app/api/agents/[id]/mcps/route.js.nft.json +0 -1
  150. package/apps/web/.next/server/app/api/agents/[id]/mcps/route_client-reference-manifest.js +0 -1
  151. package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route.js +0 -1
  152. package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route.js.nft.json +0 -1
  153. package/apps/web/.next/server/app/api/agents/[id]/memories/[memId]/route_client-reference-manifest.js +0 -1
  154. package/apps/web/.next/server/app/api/agents/[id]/memories/route.js +0 -1
  155. package/apps/web/.next/server/app/api/agents/[id]/memories/route.js.nft.json +0 -1
  156. package/apps/web/.next/server/app/api/agents/[id]/memories/route_client-reference-manifest.js +0 -1
  157. package/apps/web/.next/server/app/api/agents/[id]/permissions/route.js +0 -1
  158. package/apps/web/.next/server/app/api/agents/[id]/permissions/route.js.nft.json +0 -1
  159. package/apps/web/.next/server/app/api/agents/[id]/permissions/route_client-reference-manifest.js +0 -1
  160. package/apps/web/.next/server/app/api/agents/[id]/reload/route.js +0 -1
  161. package/apps/web/.next/server/app/api/agents/[id]/reload/route.js.nft.json +0 -1
  162. package/apps/web/.next/server/app/api/agents/[id]/reload/route_client-reference-manifest.js +0 -1
  163. package/apps/web/.next/server/app/api/agents/[id]/restrictions/route.js +0 -1
  164. package/apps/web/.next/server/app/api/agents/[id]/restrictions/route.js.nft.json +0 -1
  165. package/apps/web/.next/server/app/api/agents/[id]/restrictions/route_client-reference-manifest.js +0 -1
  166. package/apps/web/.next/server/app/api/agents/[id]/route.js +0 -33
  167. package/apps/web/.next/server/app/api/agents/[id]/route.js.nft.json +0 -1
  168. package/apps/web/.next/server/app/api/agents/[id]/route_client-reference-manifest.js +0 -1
  169. package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route.js +0 -1
  170. package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route.js.nft.json +0 -1
  171. package/apps/web/.next/server/app/api/agents/[id]/skills/[skillId]/route_client-reference-manifest.js +0 -1
  172. package/apps/web/.next/server/app/api/agents/[id]/skills/route.js +0 -1
  173. package/apps/web/.next/server/app/api/agents/[id]/skills/route.js.nft.json +0 -1
  174. package/apps/web/.next/server/app/api/agents/[id]/skills/route_client-reference-manifest.js +0 -1
  175. package/apps/web/.next/server/app/api/agents/[id]/slack-info/route.js +0 -1
  176. package/apps/web/.next/server/app/api/agents/[id]/slack-info/route.js.nft.json +0 -1
  177. package/apps/web/.next/server/app/api/agents/[id]/slack-info/route_client-reference-manifest.js +0 -1
  178. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route.js +0 -1
  179. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route.js.nft.json +0 -1
  180. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/restore/route_client-reference-manifest.js +0 -1
  181. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route.js +0 -1
  182. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route.js.nft.json +0 -1
  183. package/apps/web/.next/server/app/api/agents/[id]/snapshots/[sid]/route_client-reference-manifest.js +0 -1
  184. package/apps/web/.next/server/app/api/agents/[id]/snapshots/route.js +0 -1
  185. package/apps/web/.next/server/app/api/agents/[id]/snapshots/route.js.nft.json +0 -1
  186. package/apps/web/.next/server/app/api/agents/[id]/snapshots/route_client-reference-manifest.js +0 -1
  187. package/apps/web/.next/server/app/api/agents/[id]/start/route.js +0 -1
  188. package/apps/web/.next/server/app/api/agents/[id]/start/route.js.nft.json +0 -1
  189. package/apps/web/.next/server/app/api/agents/[id]/start/route_client-reference-manifest.js +0 -1
  190. package/apps/web/.next/server/app/api/agents/[id]/stop/route.js +0 -1
  191. package/apps/web/.next/server/app/api/agents/[id]/stop/route.js.nft.json +0 -1
  192. package/apps/web/.next/server/app/api/agents/[id]/stop/route_client-reference-manifest.js +0 -1
  193. package/apps/web/.next/server/app/api/agents/route.js +0 -91
  194. package/apps/web/.next/server/app/api/agents/route.js.nft.json +0 -1
  195. package/apps/web/.next/server/app/api/agents/route_client-reference-manifest.js +0 -1
  196. package/apps/web/.next/server/app/api/auth/login/route.js +0 -1
  197. package/apps/web/.next/server/app/api/auth/login/route.js.nft.json +0 -1
  198. package/apps/web/.next/server/app/api/auth/login/route_client-reference-manifest.js +0 -1
  199. package/apps/web/.next/server/app/api/auth/logout/route.js +0 -1
  200. package/apps/web/.next/server/app/api/auth/logout/route.js.nft.json +0 -1
  201. package/apps/web/.next/server/app/api/auth/logout/route_client-reference-manifest.js +0 -1
  202. package/apps/web/.next/server/app/api/auth/me/route.js +0 -1
  203. package/apps/web/.next/server/app/api/auth/me/route.js.nft.json +0 -1
  204. package/apps/web/.next/server/app/api/auth/me/route_client-reference-manifest.js +0 -1
  205. package/apps/web/.next/server/app/api/auth/users/[id]/route.js +0 -1
  206. package/apps/web/.next/server/app/api/auth/users/[id]/route.js.nft.json +0 -1
  207. package/apps/web/.next/server/app/api/auth/users/[id]/route_client-reference-manifest.js +0 -1
  208. package/apps/web/.next/server/app/api/auth/users/route.js +0 -1
  209. package/apps/web/.next/server/app/api/auth/users/route.js.nft.json +0 -1
  210. package/apps/web/.next/server/app/api/auth/users/route_client-reference-manifest.js +0 -1
  211. package/apps/web/.next/server/app/api/env-vars/[key]/route.js +0 -1
  212. package/apps/web/.next/server/app/api/env-vars/[key]/route.js.nft.json +0 -1
  213. package/apps/web/.next/server/app/api/env-vars/[key]/route_client-reference-manifest.js +0 -1
  214. package/apps/web/.next/server/app/api/env-vars/route.js +0 -1
  215. package/apps/web/.next/server/app/api/env-vars/route.js.nft.json +0 -1
  216. package/apps/web/.next/server/app/api/env-vars/route_client-reference-manifest.js +0 -1
  217. package/apps/web/.next/server/app/api/jobs/[id]/route.js +0 -1
  218. package/apps/web/.next/server/app/api/jobs/[id]/route.js.nft.json +0 -1
  219. package/apps/web/.next/server/app/api/jobs/[id]/route_client-reference-manifest.js +0 -1
  220. package/apps/web/.next/server/app/api/jobs/[id]/runs/route.js +0 -1
  221. package/apps/web/.next/server/app/api/jobs/[id]/runs/route.js.nft.json +0 -1
  222. package/apps/web/.next/server/app/api/jobs/[id]/runs/route_client-reference-manifest.js +0 -1
  223. package/apps/web/.next/server/app/api/jobs/route.js +0 -1
  224. package/apps/web/.next/server/app/api/jobs/route.js.nft.json +0 -1
  225. package/apps/web/.next/server/app/api/jobs/route_client-reference-manifest.js +0 -1
  226. package/apps/web/.next/server/app/api/mcps/[id]/route.js +0 -1
  227. package/apps/web/.next/server/app/api/mcps/[id]/route.js.nft.json +0 -1
  228. package/apps/web/.next/server/app/api/mcps/[id]/route_client-reference-manifest.js +0 -1
  229. package/apps/web/.next/server/app/api/mcps/[id]/test/route.js +0 -1
  230. package/apps/web/.next/server/app/api/mcps/[id]/test/route.js.nft.json +0 -1
  231. package/apps/web/.next/server/app/api/mcps/[id]/test/route_client-reference-manifest.js +0 -1
  232. package/apps/web/.next/server/app/api/mcps/route.js +0 -1
  233. package/apps/web/.next/server/app/api/mcps/route.js.nft.json +0 -1
  234. package/apps/web/.next/server/app/api/mcps/route_client-reference-manifest.js +0 -1
  235. package/apps/web/.next/server/app/api/settings/route.js +0 -1
  236. package/apps/web/.next/server/app/api/settings/route.js.nft.json +0 -1
  237. package/apps/web/.next/server/app/api/settings/route_client-reference-manifest.js +0 -1
  238. package/apps/web/.next/server/app/icon.svg/route.js +0 -1
  239. package/apps/web/.next/server/app/icon.svg/route.js.nft.json +0 -1
  240. package/apps/web/.next/server/app/jobs/page.js +0 -2
  241. package/apps/web/.next/server/app/jobs/page.js.nft.json +0 -1
  242. package/apps/web/.next/server/app/jobs/page_client-reference-manifest.js +0 -1
  243. package/apps/web/.next/server/app/login/page.js +0 -2
  244. package/apps/web/.next/server/app/login/page.js.nft.json +0 -1
  245. package/apps/web/.next/server/app/login/page_client-reference-manifest.js +0 -1
  246. package/apps/web/.next/server/app/page.js +0 -2
  247. package/apps/web/.next/server/app/page.js.nft.json +0 -1
  248. package/apps/web/.next/server/app/page_client-reference-manifest.js +0 -1
  249. package/apps/web/.next/server/app/settings/env-vars/page.js +0 -2
  250. package/apps/web/.next/server/app/settings/env-vars/page.js.nft.json +0 -1
  251. package/apps/web/.next/server/app/settings/env-vars/page_client-reference-manifest.js +0 -1
  252. package/apps/web/.next/server/app/settings/mcps/page.js +0 -2
  253. package/apps/web/.next/server/app/settings/mcps/page.js.nft.json +0 -1
  254. package/apps/web/.next/server/app/settings/mcps/page_client-reference-manifest.js +0 -1
  255. package/apps/web/.next/server/app/settings/page.js +0 -2
  256. package/apps/web/.next/server/app/settings/page.js.nft.json +0 -1
  257. package/apps/web/.next/server/app/settings/page_client-reference-manifest.js +0 -1
  258. package/apps/web/.next/server/app-paths-manifest.json +0 -46
  259. package/apps/web/.next/server/chunks/1157.js +0 -9
  260. package/apps/web/.next/server/chunks/2287.js +0 -1
  261. package/apps/web/.next/server/chunks/3444.js +0 -1
  262. package/apps/web/.next/server/chunks/383.js +0 -6
  263. package/apps/web/.next/server/chunks/4012.js +0 -58
  264. package/apps/web/.next/server/chunks/6791.js +0 -1
  265. package/apps/web/.next/server/chunks/7171.js +0 -1
  266. package/apps/web/.next/server/chunks/8819.js +0 -22
  267. package/apps/web/.next/server/edge-runtime-webpack.js +0 -2
  268. package/apps/web/.next/server/edge-runtime-webpack.js.map +0 -1
  269. package/apps/web/.next/server/interception-route-rewrite-manifest.js +0 -1
  270. package/apps/web/.next/server/middleware-build-manifest.js +0 -1
  271. package/apps/web/.next/server/middleware-manifest.json +0 -32
  272. package/apps/web/.next/server/middleware-react-loadable-manifest.js +0 -1
  273. package/apps/web/.next/server/next-font-manifest.js +0 -1
  274. package/apps/web/.next/server/next-font-manifest.json +0 -1
  275. package/apps/web/.next/server/pages/_app.js +0 -1
  276. package/apps/web/.next/server/pages/_app.js.nft.json +0 -1
  277. package/apps/web/.next/server/pages/_document.js +0 -1
  278. package/apps/web/.next/server/pages/_document.js.nft.json +0 -1
  279. package/apps/web/.next/server/pages/_error.js +0 -19
  280. package/apps/web/.next/server/pages/_error.js.nft.json +0 -1
  281. package/apps/web/.next/server/pages-manifest.json +0 -5
  282. package/apps/web/.next/server/server-reference-manifest.js +0 -1
  283. package/apps/web/.next/server/server-reference-manifest.json +0 -1
  284. package/apps/web/.next/server/src/middleware.js +0 -14
  285. package/apps/web/.next/server/src/middleware.js.map +0 -1
  286. package/apps/web/.next/server/webpack-runtime.js +0 -1
  287. package/apps/web/.next/static/chunks/18-90b700ea37b686a2.js +0 -1
  288. package/apps/web/.next/static/chunks/87c73c54-24122e7b92478d00.js +0 -1
  289. package/apps/web/.next/static/chunks/9664-af80478aa73ba424.js +0 -1
  290. package/apps/web/.next/static/chunks/app/_not-found/page-b9cee17ed89ca24a.js +0 -1
  291. package/apps/web/.next/static/chunks/app/agents/[slug]/page-18369fc3fe1a9a7b.js +0 -1
  292. package/apps/web/.next/static/chunks/app/agents/new/page-bf11cf8901c7e2cd.js +0 -1
  293. package/apps/web/.next/static/chunks/app/api/agents/[id]/access/route-07f0f73ac9839899.js +0 -1
  294. package/apps/web/.next/static/chunks/app/api/agents/[id]/claude-md/route-07f0f73ac9839899.js +0 -1
  295. package/apps/web/.next/static/chunks/app/api/agents/[id]/logs/route-07f0f73ac9839899.js +0 -1
  296. package/apps/web/.next/static/chunks/app/api/agents/[id]/manifest/route-07f0f73ac9839899.js +0 -1
  297. package/apps/web/.next/static/chunks/app/api/agents/[id]/mcps/route-07f0f73ac9839899.js +0 -1
  298. package/apps/web/.next/static/chunks/app/api/agents/[id]/memories/[memId]/route-07f0f73ac9839899.js +0 -1
  299. package/apps/web/.next/static/chunks/app/api/agents/[id]/memories/route-07f0f73ac9839899.js +0 -1
  300. package/apps/web/.next/static/chunks/app/api/agents/[id]/permissions/route-07f0f73ac9839899.js +0 -1
  301. package/apps/web/.next/static/chunks/app/api/agents/[id]/reload/route-07f0f73ac9839899.js +0 -1
  302. package/apps/web/.next/static/chunks/app/api/agents/[id]/restrictions/route-07f0f73ac9839899.js +0 -1
  303. package/apps/web/.next/static/chunks/app/api/agents/[id]/route-07f0f73ac9839899.js +0 -1
  304. package/apps/web/.next/static/chunks/app/api/agents/[id]/skills/[skillId]/route-07f0f73ac9839899.js +0 -1
  305. package/apps/web/.next/static/chunks/app/api/agents/[id]/skills/route-07f0f73ac9839899.js +0 -1
  306. package/apps/web/.next/static/chunks/app/api/agents/[id]/slack-info/route-07f0f73ac9839899.js +0 -1
  307. package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/[sid]/restore/route-07f0f73ac9839899.js +0 -1
  308. package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/[sid]/route-07f0f73ac9839899.js +0 -1
  309. package/apps/web/.next/static/chunks/app/api/agents/[id]/snapshots/route-07f0f73ac9839899.js +0 -1
  310. package/apps/web/.next/static/chunks/app/api/agents/[id]/start/route-07f0f73ac9839899.js +0 -1
  311. package/apps/web/.next/static/chunks/app/api/agents/[id]/stop/route-07f0f73ac9839899.js +0 -1
  312. package/apps/web/.next/static/chunks/app/api/agents/route-07f0f73ac9839899.js +0 -1
  313. package/apps/web/.next/static/chunks/app/api/auth/login/route-07f0f73ac9839899.js +0 -1
  314. package/apps/web/.next/static/chunks/app/api/auth/logout/route-07f0f73ac9839899.js +0 -1
  315. package/apps/web/.next/static/chunks/app/api/auth/me/route-07f0f73ac9839899.js +0 -1
  316. package/apps/web/.next/static/chunks/app/api/auth/users/[id]/route-07f0f73ac9839899.js +0 -1
  317. package/apps/web/.next/static/chunks/app/api/auth/users/route-07f0f73ac9839899.js +0 -1
  318. package/apps/web/.next/static/chunks/app/api/env-vars/[key]/route-07f0f73ac9839899.js +0 -1
  319. package/apps/web/.next/static/chunks/app/api/env-vars/route-07f0f73ac9839899.js +0 -1
  320. package/apps/web/.next/static/chunks/app/api/jobs/[id]/route-07f0f73ac9839899.js +0 -1
  321. package/apps/web/.next/static/chunks/app/api/jobs/[id]/runs/route-07f0f73ac9839899.js +0 -1
  322. package/apps/web/.next/static/chunks/app/api/jobs/route-07f0f73ac9839899.js +0 -1
  323. package/apps/web/.next/static/chunks/app/api/mcps/[id]/route-07f0f73ac9839899.js +0 -1
  324. package/apps/web/.next/static/chunks/app/api/mcps/[id]/test/route-07f0f73ac9839899.js +0 -1
  325. package/apps/web/.next/static/chunks/app/api/mcps/route-07f0f73ac9839899.js +0 -1
  326. package/apps/web/.next/static/chunks/app/api/settings/route-07f0f73ac9839899.js +0 -1
  327. package/apps/web/.next/static/chunks/app/jobs/page-f5aa89a47c50efd8.js +0 -1
  328. package/apps/web/.next/static/chunks/app/layout-2079f4964aa7314e.js +0 -1
  329. package/apps/web/.next/static/chunks/app/login/layout-07f0f73ac9839899.js +0 -1
  330. package/apps/web/.next/static/chunks/app/login/page-aa259283dc38e8f9.js +0 -1
  331. package/apps/web/.next/static/chunks/app/page-e83437b608104dff.js +0 -1
  332. package/apps/web/.next/static/chunks/app/settings/env-vars/page-06479dbdfb78b76b.js +0 -1
  333. package/apps/web/.next/static/chunks/app/settings/mcps/page-75650686ed6490c7.js +0 -1
  334. package/apps/web/.next/static/chunks/app/settings/page-e1e62fc41ff6cddd.js +0 -1
  335. package/apps/web/.next/static/chunks/framework-811407f832a33072.js +0 -1
  336. package/apps/web/.next/static/chunks/main-3f1cddbdd67b1546.js +0 -1
  337. package/apps/web/.next/static/chunks/main-app-cebd8a6a5ccbf72d.js +0 -1
  338. package/apps/web/.next/static/chunks/pages/_app-50fa07b56b2d29ac.js +0 -1
  339. package/apps/web/.next/static/chunks/pages/_error-fed8688bdd23f211.js +0 -1
  340. package/apps/web/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  341. package/apps/web/.next/static/chunks/webpack-6c05566dba553c97.js +0 -1
  342. package/apps/web/.next/static/css/15371687405525e2.css +0 -5
  343. package/apps/web/.next/static/ikfNbLhuw7jntn35bz0lk/_buildManifest.js +0 -1
  344. package/apps/web/.next/static/ikfNbLhuw7jntn35bz0lk/_ssgManifest.js +0 -1
  345. package/apps/web/.next/trace +0 -5
  346. package/apps/web/.next/types/app/agents/[slug]/page.ts +0 -84
  347. package/apps/web/.next/types/app/agents/new/page.ts +0 -84
  348. package/apps/web/.next/types/app/api/agents/[id]/access/route.ts +0 -347
  349. package/apps/web/.next/types/app/api/agents/[id]/claude-md/route.ts +0 -347
  350. package/apps/web/.next/types/app/api/agents/[id]/logs/route.ts +0 -347
  351. package/apps/web/.next/types/app/api/agents/[id]/manifest/route.ts +0 -347
  352. package/apps/web/.next/types/app/api/agents/[id]/mcps/route.ts +0 -347
  353. package/apps/web/.next/types/app/api/agents/[id]/memories/[memId]/route.ts +0 -347
  354. package/apps/web/.next/types/app/api/agents/[id]/memories/route.ts +0 -347
  355. package/apps/web/.next/types/app/api/agents/[id]/permissions/route.ts +0 -347
  356. package/apps/web/.next/types/app/api/agents/[id]/reload/route.ts +0 -347
  357. package/apps/web/.next/types/app/api/agents/[id]/restrictions/route.ts +0 -347
  358. package/apps/web/.next/types/app/api/agents/[id]/route.ts +0 -347
  359. package/apps/web/.next/types/app/api/agents/[id]/skills/[skillId]/route.ts +0 -347
  360. package/apps/web/.next/types/app/api/agents/[id]/skills/route.ts +0 -347
  361. package/apps/web/.next/types/app/api/agents/[id]/slack-info/route.ts +0 -347
  362. package/apps/web/.next/types/app/api/agents/[id]/snapshots/[sid]/restore/route.ts +0 -347
  363. package/apps/web/.next/types/app/api/agents/[id]/snapshots/[sid]/route.ts +0 -347
  364. package/apps/web/.next/types/app/api/agents/[id]/snapshots/route.ts +0 -347
  365. package/apps/web/.next/types/app/api/agents/[id]/start/route.ts +0 -347
  366. package/apps/web/.next/types/app/api/agents/[id]/stop/route.ts +0 -347
  367. package/apps/web/.next/types/app/api/agents/route.ts +0 -347
  368. package/apps/web/.next/types/app/api/auth/login/route.ts +0 -347
  369. package/apps/web/.next/types/app/api/auth/logout/route.ts +0 -347
  370. package/apps/web/.next/types/app/api/auth/me/route.ts +0 -347
  371. package/apps/web/.next/types/app/api/auth/users/[id]/route.ts +0 -347
  372. package/apps/web/.next/types/app/api/auth/users/route.ts +0 -347
  373. package/apps/web/.next/types/app/api/env-vars/[key]/route.ts +0 -347
  374. package/apps/web/.next/types/app/api/env-vars/route.ts +0 -347
  375. package/apps/web/.next/types/app/api/jobs/[id]/route.ts +0 -347
  376. package/apps/web/.next/types/app/api/jobs/[id]/runs/route.ts +0 -347
  377. package/apps/web/.next/types/app/api/jobs/route.ts +0 -347
  378. package/apps/web/.next/types/app/api/mcps/[id]/route.ts +0 -347
  379. package/apps/web/.next/types/app/api/mcps/[id]/test/route.ts +0 -347
  380. package/apps/web/.next/types/app/api/mcps/route.ts +0 -347
  381. package/apps/web/.next/types/app/api/settings/route.ts +0 -347
  382. package/apps/web/.next/types/app/jobs/page.ts +0 -84
  383. package/apps/web/.next/types/app/login/layout.ts +0 -84
  384. package/apps/web/.next/types/app/login/page.ts +0 -84
  385. package/apps/web/.next/types/app/page.ts +0 -84
  386. package/apps/web/.next/types/app/settings/env-vars/page.ts +0 -84
  387. package/apps/web/.next/types/app/settings/mcps/page.ts +0 -84
  388. package/apps/web/.next/types/app/settings/page.ts +0 -84
  389. package/apps/web/.next/types/cache-life.d.ts +0 -141
  390. package/apps/web/.next/types/package.json +0 -1
  391. package/apps/web/.next/types/routes.d.ts +0 -114
  392. package/apps/web/.next/types/validator.ts +0 -448
  393. package/apps/web/Dockerfile +0 -37
  394. package/apps/web/next-env.d.ts +0 -6
  395. package/apps/web/next.config.js +0 -6
  396. package/apps/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  397. package/apps/web/package.json +0 -48
  398. package/apps/web/postcss.config.js +0 -3
  399. package/apps/web/public/logo.svg +0 -17
  400. package/apps/web/src/app/agents/[slug]/page.tsx +0 -2235
  401. package/apps/web/src/app/agents/new/page.tsx +0 -1161
  402. package/apps/web/src/app/api/agents/[id]/access/route.ts +0 -76
  403. package/apps/web/src/app/api/agents/[id]/claude-md/route.ts +0 -111
  404. package/apps/web/src/app/api/agents/[id]/logs/route.ts +0 -84
  405. package/apps/web/src/app/api/agents/[id]/manifest/route.ts +0 -32
  406. package/apps/web/src/app/api/agents/[id]/mcps/route.ts +0 -73
  407. package/apps/web/src/app/api/agents/[id]/memories/[memId]/route.ts +0 -31
  408. package/apps/web/src/app/api/agents/[id]/memories/route.ts +0 -56
  409. package/apps/web/src/app/api/agents/[id]/permissions/route.ts +0 -74
  410. package/apps/web/src/app/api/agents/[id]/reload/route.ts +0 -33
  411. package/apps/web/src/app/api/agents/[id]/restrictions/route.ts +0 -85
  412. package/apps/web/src/app/api/agents/[id]/route.ts +0 -81
  413. package/apps/web/src/app/api/agents/[id]/skills/[skillId]/route.ts +0 -52
  414. package/apps/web/src/app/api/agents/[id]/skills/route.ts +0 -80
  415. package/apps/web/src/app/api/agents/[id]/slack-info/route.ts +0 -38
  416. package/apps/web/src/app/api/agents/[id]/snapshots/[sid]/restore/route.ts +0 -61
  417. package/apps/web/src/app/api/agents/[id]/snapshots/[sid]/route.ts +0 -53
  418. package/apps/web/src/app/api/agents/[id]/snapshots/route.ts +0 -84
  419. package/apps/web/src/app/api/agents/[id]/start/route.ts +0 -35
  420. package/apps/web/src/app/api/agents/[id]/stop/route.ts +0 -35
  421. package/apps/web/src/app/api/agents/route.ts +0 -99
  422. package/apps/web/src/app/api/auth/login/route.ts +0 -39
  423. package/apps/web/src/app/api/auth/logout/route.ts +0 -21
  424. package/apps/web/src/app/api/auth/me/route.ts +0 -24
  425. package/apps/web/src/app/api/auth/users/[id]/route.ts +0 -48
  426. package/apps/web/src/app/api/auth/users/route.ts +0 -63
  427. package/apps/web/src/app/api/env-vars/[key]/route.ts +0 -66
  428. package/apps/web/src/app/api/env-vars/route.ts +0 -59
  429. package/apps/web/src/app/api/jobs/[id]/route.ts +0 -51
  430. package/apps/web/src/app/api/jobs/[id]/runs/route.ts +0 -24
  431. package/apps/web/src/app/api/jobs/route.ts +0 -42
  432. package/apps/web/src/app/api/mcps/[id]/route.ts +0 -60
  433. package/apps/web/src/app/api/mcps/[id]/test/route.ts +0 -195
  434. package/apps/web/src/app/api/mcps/route.ts +0 -72
  435. package/apps/web/src/app/api/settings/route.ts +0 -42
  436. package/apps/web/src/app/globals.css +0 -124
  437. package/apps/web/src/app/icon.svg +0 -17
  438. package/apps/web/src/app/jobs/page.tsx +0 -543
  439. package/apps/web/src/app/layout-shell.tsx +0 -89
  440. package/apps/web/src/app/layout.tsx +0 -18
  441. package/apps/web/src/app/login/layout.tsx +0 -9
  442. package/apps/web/src/app/login/page.tsx +0 -150
  443. package/apps/web/src/app/page.tsx +0 -573
  444. package/apps/web/src/app/settings/env-vars/page.tsx +0 -216
  445. package/apps/web/src/app/settings/mcps/page.tsx +0 -763
  446. package/apps/web/src/app/settings/page.tsx +0 -528
  447. package/apps/web/src/app/sidebar.tsx +0 -345
  448. package/apps/web/src/lib/__tests__/api-guard.test.ts +0 -189
  449. package/apps/web/src/lib/__tests__/auth.test.ts +0 -262
  450. package/apps/web/src/lib/__tests__/boss-registry.test.ts +0 -323
  451. package/apps/web/src/lib/__tests__/compile.test.ts +0 -161
  452. package/apps/web/src/lib/__tests__/db-agent-hierarchy.test.ts +0 -136
  453. package/apps/web/src/lib/__tests__/db-env-vars.test.ts +0 -216
  454. package/apps/web/src/lib/__tests__/db-restrictions.test.ts +0 -117
  455. package/apps/web/src/lib/__tests__/db.integration.test.ts +0 -271
  456. package/apps/web/src/lib/__tests__/diff.test.ts +0 -102
  457. package/apps/web/src/lib/__tests__/mcp-mask.test.ts +0 -274
  458. package/apps/web/src/lib/__tests__/skill-templates.test.ts +0 -237
  459. package/apps/web/src/lib/__tests__/slack-manifest.test.ts +0 -105
  460. package/apps/web/src/lib/api-guard.ts +0 -68
  461. package/apps/web/src/lib/auth-context.tsx +0 -71
  462. package/apps/web/src/lib/auth.ts +0 -128
  463. package/apps/web/src/lib/boss-registry.ts +0 -90
  464. package/apps/web/src/lib/compile.ts +0 -51
  465. package/apps/web/src/lib/db.ts +0 -1196
  466. package/apps/web/src/lib/diff.ts +0 -43
  467. package/apps/web/src/lib/mcp-mask.ts +0 -91
  468. package/apps/web/src/lib/portal.tsx +0 -23
  469. package/apps/web/src/lib/skill-templates.ts +0 -148
  470. package/apps/web/src/lib/slack-manifest.ts +0 -85
  471. package/apps/web/src/middleware.ts +0 -68
  472. package/apps/web/tailwind.config.js +0 -6
  473. package/apps/web/tsconfig.json +0 -23
  474. package/apps/web/vitest.config.mts +0 -21
  475. package/cli/.claude/settings.local.json +0 -6
  476. package/cli/node_modules/.package-lock.json +0 -427
  477. package/cli/node_modules/commander/LICENSE +0 -22
  478. package/cli/node_modules/commander/Readme.md +0 -1157
  479. package/cli/node_modules/commander/esm.mjs +0 -16
  480. package/cli/node_modules/commander/index.js +0 -24
  481. package/cli/node_modules/commander/lib/argument.js +0 -149
  482. package/cli/node_modules/commander/lib/command.js +0 -2509
  483. package/cli/node_modules/commander/lib/error.js +0 -39
  484. package/cli/node_modules/commander/lib/help.js +0 -520
  485. package/cli/node_modules/commander/lib/option.js +0 -330
  486. package/cli/node_modules/commander/lib/suggestSimilar.js +0 -101
  487. package/cli/node_modules/commander/package-support.json +0 -16
  488. package/cli/node_modules/commander/package.json +0 -84
  489. package/cli/node_modules/commander/typings/esm.d.mts +0 -3
  490. package/cli/node_modules/commander/typings/index.d.ts +0 -969
  491. package/cli/package-lock.json +0 -449
  492. package/cli/package.json +0 -44
  493. package/cli/src/commands/init.ts +0 -514
  494. package/cli/src/commands/manage.ts +0 -115
  495. package/cli/src/index.ts +0 -63
  496. package/cli/tsconfig.json +0 -14
  497. package/docker-compose.yml +0 -122
  498. package/docs/agents/boss-agents.mdx +0 -108
  499. package/docs/agents/creating-agents.mdx +0 -132
  500. package/docs/agents/memory.mdx +0 -113
  501. package/docs/agents/tools.mdx +0 -103
  502. package/docs/configuration/env-vars.mdx +0 -166
  503. package/docs/configuration/mcp-servers.mdx +0 -203
  504. package/docs/configuration/slack-app.mdx +0 -175
  505. package/docs/docs.json +0 -79
  506. package/docs/favicon.svg +0 -17
  507. package/docs/features/history.mdx +0 -60
  508. package/docs/features/import-export.mdx +0 -77
  509. package/docs/features/logs.mdx +0 -131
  510. package/docs/features/multi-workspace.mdx +0 -90
  511. package/docs/features/scheduled-jobs.mdx +0 -231
  512. package/docs/features/users.mdx +0 -92
  513. package/docs/introduction.mdx +0 -160
  514. package/docs/logo/dark.svg +0 -17
  515. package/docs/logo/light.svg +0 -17
  516. package/docs/logo/wide-dark.svg +0 -12
  517. package/docs/logo/wide-light.svg +0 -12
  518. package/docs/quickstart.mdx +0 -270
  519. package/docs/self-hosting/docker.mdx +0 -151
  520. package/docs/self-hosting/production.mdx +0 -176
  521. package/packages/shared/dist/index.d.ts +0 -8
  522. package/packages/shared/dist/index.d.ts.map +0 -1
  523. package/packages/shared/dist/index.js +0 -24
  524. package/packages/shared/dist/index.js.map +0 -1
  525. package/packages/shared/dist/types.d.ts +0 -584
  526. package/packages/shared/dist/types.d.ts.map +0 -1
  527. package/packages/shared/dist/types.js +0 -39
  528. package/packages/shared/dist/types.js.map +0 -1
  529. package/packages/shared/package.json +0 -15
  530. package/packages/shared/src/db/schema.sql +0 -354
  531. package/packages/shared/src/index.ts +0 -8
  532. package/packages/shared/src/types.ts +0 -683
  533. package/packages/shared/tsconfig.json +0 -17
  534. package/scripts/dev.sh +0 -45
@@ -1,528 +0,0 @@
1
- 'use client';
2
-
3
- /**
4
- * @fileoverview Platform settings page — branding, dashboard, and user management.
5
- *
6
- * Tabs: General · Users (admin only)
7
- *
8
- * @module web/app/settings
9
- */
10
-
11
- import React, { useEffect, useState } from 'react';
12
- import { Portal } from '@/lib/portal';
13
- import { useAuth } from '@/lib/auth-context';
14
-
15
- type Tab = 'general' | 'users';
16
-
17
- interface User {
18
- id: string;
19
- username: string;
20
- role: string;
21
- createdAt: string;
22
- }
23
-
24
- interface AgentBasic {
25
- id: string;
26
- name: string;
27
- slug: string;
28
- }
29
-
30
- const DEFAULTS: Record<string, string> = {
31
- appName: 'SlackHive',
32
- tagline: 'AI agent teams on Slack',
33
- logoUrl: '',
34
- dashboardTitle: 'Welcome to SlackHive',
35
- };
36
-
37
- /**
38
- * Settings page with General and Users tabs.
39
- *
40
- * @returns {JSX.Element}
41
- */
42
- export default function SettingsPage() {
43
- const { canEdit, canManageUsers } = useAuth();
44
- const [tab, setTab] = useState<Tab>('general');
45
-
46
- return (
47
- <div className="fade-up" style={{ padding: '36px 40px' }}>
48
- {/* Header */}
49
- <div style={{ marginBottom: 24 }}>
50
- <h1 style={{ fontSize: 22, fontWeight: 700, color: 'var(--text)', letterSpacing: '-0.02em', margin: 0 }}>
51
- Settings
52
- </h1>
53
- <p style={{ fontSize: 13, color: 'var(--muted)', marginTop: 4 }}>
54
- Configure platform branding, appearance, and access.
55
- </p>
56
- </div>
57
-
58
- {/* Tabs */}
59
- <div style={{ display: 'flex', gap: 0, borderBottom: '1px solid var(--border)', marginBottom: 24 }}>
60
- <TabBtn active={tab === 'general'} onClick={() => setTab('general')}>General</TabBtn>
61
- {canManageUsers && <TabBtn active={tab === 'users'} onClick={() => setTab('users')}>Users</TabBtn>}
62
- </div>
63
-
64
- {tab === 'general' && <GeneralTab />}
65
- {tab === 'users' && canManageUsers && <UsersTab />}
66
- </div>
67
- );
68
- }
69
-
70
- // =============================================================================
71
- // General tab
72
- // =============================================================================
73
-
74
- function GeneralTab() {
75
- const [appName, setAppName] = useState(DEFAULTS.appName);
76
- const [tagline, setTagline] = useState(DEFAULTS.tagline);
77
- const [logoUrl, setLogoUrl] = useState(DEFAULTS.logoUrl);
78
- const [dashboardTitle, setDashboardTitle] = useState(DEFAULTS.dashboardTitle);
79
- const [saving, setSaving] = useState(false);
80
- const [toast, setToast] = useState('');
81
-
82
- useEffect(() => {
83
- fetch('/api/settings')
84
- .then(r => r.json())
85
- .then((s: Record<string, string>) => {
86
- if (s.appName) setAppName(s.appName);
87
- if (s.tagline) setTagline(s.tagline);
88
- if (s.logoUrl !== undefined && s.logoUrl !== '') setLogoUrl(s.logoUrl);
89
- if (s.dashboardTitle) setDashboardTitle(s.dashboardTitle);
90
- })
91
- .catch(() => {});
92
- }, []);
93
-
94
- async function save(key: string, value: string) {
95
- setSaving(true);
96
- try {
97
- await fetch('/api/settings', {
98
- method: 'PUT', headers: { 'Content-Type': 'application/json' },
99
- body: JSON.stringify({ key, value }),
100
- });
101
- setToast(`Saved`);
102
- setTimeout(() => setToast(''), 2000);
103
- } finally { setSaving(false); }
104
- }
105
-
106
- async function saveAll() {
107
- setSaving(true);
108
- try {
109
- await Promise.all([
110
- fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'appName', value: appName }) }),
111
- fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'tagline', value: tagline }) }),
112
- fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'logoUrl', value: logoUrl }) }),
113
- fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'dashboardTitle', value: dashboardTitle }) }),
114
- ]);
115
- setToast('All settings saved');
116
- setTimeout(() => setToast(''), 2000);
117
- } finally { setSaving(false); }
118
- }
119
-
120
- return (
121
- <>
122
- {toast && (
123
- <div style={{
124
- position: 'fixed', top: 20, right: 20, zIndex: 999,
125
- background: 'var(--accent)', color: '#fff',
126
- padding: '8px 16px', borderRadius: 8, fontSize: 13, fontWeight: 500,
127
- boxShadow: 'var(--shadow-md)',
128
- }}>{toast}</div>
129
- )}
130
-
131
- <Section title="Branding">
132
- <Field label="App Name" hint="Displayed in the sidebar header and browser tab."
133
- value={appName} onChange={setAppName} onBlur={() => save('appName', appName)} />
134
- <Field label="Tagline" hint="Short description shown below the app name."
135
- value={tagline} onChange={setTagline} onBlur={() => save('tagline', tagline)} />
136
- <Field label="Logo URL" hint="URL to a square image (28×28). Leave empty for the default icon."
137
- value={logoUrl} onChange={setLogoUrl} onBlur={() => save('logoUrl', logoUrl)} />
138
- <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 4 }}>
139
- <div style={{ fontSize: 12, fontWeight: 500, color: 'var(--muted)' }}>Preview:</div>
140
- {/* eslint-disable-next-line @next/next/no-img-element */}
141
- <img src={logoUrl || '/logo.svg'} alt="Logo" style={{ width: 28, height: 28, borderRadius: 8, objectFit: 'cover' }} />
142
- {!logoUrl && <span style={{ fontSize: 11, color: 'var(--subtle)', fontStyle: 'italic' }}>Using default logo</span>}
143
- </div>
144
- </Section>
145
-
146
- <Section title="Dashboard">
147
- <Field label="Dashboard Title" hint="Main heading on the dashboard page."
148
- value={dashboardTitle} onChange={setDashboardTitle} onBlur={() => save('dashboardTitle', dashboardTitle)} />
149
- </Section>
150
-
151
- <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 8 }}>
152
- <PrimaryBtn onClick={saveAll} loading={saving}>Save All</PrimaryBtn>
153
- </div>
154
- </>
155
- );
156
- }
157
-
158
- // =============================================================================
159
- // Users tab
160
- // =============================================================================
161
-
162
- function UsersTab() {
163
- const [users, setUsers] = useState<User[]>([]);
164
- const [agents, setAgents] = useState<AgentBasic[]>([]);
165
- const [loading, setLoading] = useState(true);
166
- const [showForm, setShowForm] = useState(false);
167
- const [newUser, setNewUser] = useState({ username: '', password: '', role: 'viewer' });
168
- const [error, setError] = useState('');
169
- const [saving, setSaving] = useState(false);
170
- const [updatingRole, setUpdatingRole] = useState<string | null>(null);
171
- const [expandedUser, setExpandedUser] = useState<string | null>(null);
172
- // Map of userId → set of agentIds with write access
173
- const [writeGrants, setWriteGrants] = useState<Record<string, Set<string>>>({});
174
- const [loadingGrants, setLoadingGrants] = useState<string | null>(null);
175
-
176
- const load = () => {
177
- setLoading(true);
178
- Promise.all([
179
- fetch('/api/auth/users').then(r => r.json()),
180
- fetch('/api/agents').then(r => r.json()),
181
- ]).then(([u, a]) => { setUsers(u); setAgents(a); }).catch(() => {}).finally(() => setLoading(false));
182
- };
183
- useEffect(() => { load(); }, []);
184
-
185
- const create = async () => {
186
- if (!newUser.username || !newUser.password) { setError('Username and password required'); return; }
187
- setSaving(true); setError('');
188
- try {
189
- const r = await fetch('/api/auth/users', {
190
- method: 'POST', headers: { 'Content-Type': 'application/json' },
191
- body: JSON.stringify(newUser),
192
- });
193
- const data = await r.json();
194
- if (!r.ok) { setError(data.error || 'Failed'); return; }
195
- setShowForm(false);
196
- setNewUser({ username: '', password: '', role: 'viewer' });
197
- load();
198
- } finally { setSaving(false); }
199
- };
200
-
201
- const remove = async (id: string, username: string) => {
202
- if (!confirm(`Delete user "${username}"?`)) return;
203
- await fetch(`/api/auth/users/${id}`, { method: 'DELETE' });
204
- load();
205
- };
206
-
207
- const changeRole = async (id: string, role: string) => {
208
- setUpdatingRole(id);
209
- await fetch(`/api/auth/users/${id}`, {
210
- method: 'PATCH', headers: { 'Content-Type': 'application/json' },
211
- body: JSON.stringify({ role }),
212
- });
213
- setUpdatingRole(null);
214
- load();
215
- };
216
-
217
- const toggleExpand = async (userId: string) => {
218
- if (expandedUser === userId) { setExpandedUser(null); return; }
219
- setExpandedUser(userId);
220
- if (writeGrants[userId]) return; // already loaded
221
- setLoadingGrants(userId);
222
- // Load write grants for all agents for this user by checking each agent's access
223
- // We use the admin access endpoint which returns writeUsers per agent
224
- const grants = new Set<string>();
225
- await Promise.all(agents.map(async (a) => {
226
- const r = await fetch(`/api/agents/${a.id}/access`);
227
- const data = await r.json();
228
- if (data.writeUsers?.some((w: { userId: string }) => w.userId === userId)) {
229
- grants.add(a.id);
230
- }
231
- }));
232
- setWriteGrants(prev => ({ ...prev, [userId]: grants }));
233
- setLoadingGrants(null);
234
- };
235
-
236
- const toggleWrite = async (userId: string, agentId: string, currentlyGranted: boolean) => {
237
- const method = currentlyGranted ? 'DELETE' : 'POST';
238
- await fetch(`/api/agents/${agentId}/access`, {
239
- method, headers: { 'Content-Type': 'application/json' },
240
- body: JSON.stringify({ userId }),
241
- });
242
- setWriteGrants(prev => {
243
- const next = new Set(prev[userId]);
244
- if (currentlyGranted) next.delete(agentId); else next.add(agentId);
245
- return { ...prev, [userId]: next };
246
- });
247
- };
248
-
249
- return (
250
- <>
251
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
252
- <p style={{ margin: 0, fontSize: 13, color: 'var(--muted)' }}>
253
- Manage platform access. Superadmin is configured via environment variables.
254
- </p>
255
- <button onClick={() => setShowForm(true)} style={{
256
- display: 'inline-flex', alignItems: 'center', gap: 6,
257
- background: 'var(--accent)', color: '#fff',
258
- padding: '8px 16px', borderRadius: 8,
259
- fontSize: 13, fontWeight: 500, border: 'none', cursor: 'pointer',
260
- fontFamily: 'var(--font-sans)', flexShrink: 0,
261
- }}>
262
- <svg width="12" height="12" viewBox="0 0 16 16" fill="none">
263
- <path d="M8 3v10M3 8h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
264
- </svg>
265
- Add User
266
- </button>
267
- </div>
268
-
269
- {/* User list */}
270
- {loading ? (
271
- <p style={{ color: 'var(--muted)', fontSize: 13 }}>Loading...</p>
272
- ) : (
273
- <div style={{ border: '1px solid var(--border)', borderRadius: 10, overflow: 'hidden' }}>
274
- {/* Superadmin row */}
275
- <div style={{
276
- display: 'flex', alignItems: 'center', gap: 12, padding: '12px 16px',
277
- borderBottom: users.length > 0 ? '1px solid var(--border)' : 'none',
278
- background: 'var(--surface-2)',
279
- }}>
280
- <div style={{
281
- width: 28, height: 28, borderRadius: 8, background: '#171717', flexShrink: 0,
282
- display: 'flex', alignItems: 'center', justifyContent: 'center',
283
- fontSize: 10, fontWeight: 600, color: '#fff',
284
- }}>S</div>
285
- <div style={{ flex: 1 }}>
286
- <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--text)' }}>admin</div>
287
- <div style={{ fontSize: 11, color: 'var(--muted)' }}>Environment variable</div>
288
- </div>
289
- <span style={{
290
- fontSize: 10, fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase',
291
- color: '#d97706', background: 'rgba(217,119,6,0.1)',
292
- padding: '2px 8px', borderRadius: 4,
293
- }}>superadmin</span>
294
- </div>
295
-
296
- {users.map((u, i) => (
297
- <div key={u.id} style={{ borderBottom: i < users.length - 1 ? '1px solid var(--border)' : 'none' }}>
298
- {/* User row */}
299
- <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 16px' }}>
300
- <div style={{
301
- width: 28, height: 28, borderRadius: 8, flexShrink: 0,
302
- background: u.role === 'admin' ? '#171717' : u.role === 'editor' ? '#059669' : 'var(--surface-2)',
303
- border: u.role === 'admin' ? 'none' : '1px solid var(--border)',
304
- display: 'flex', alignItems: 'center', justifyContent: 'center',
305
- fontSize: 10, fontWeight: 600, color: u.role === 'admin' ? '#fff' : 'var(--text)',
306
- }}>{u.username.charAt(0).toUpperCase()}</div>
307
- <div style={{ flex: 1 }}>
308
- <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--text)' }}>{u.username}</div>
309
- <div style={{ fontSize: 11, color: 'var(--muted)' }}>Created {new Date(u.createdAt).toLocaleDateString()}</div>
310
- </div>
311
- <select
312
- value={u.role}
313
- disabled={updatingRole === u.id}
314
- onChange={e => changeRole(u.id, e.target.value)}
315
- style={{
316
- fontSize: 11, fontWeight: 600, padding: '3px 8px', borderRadius: 5,
317
- border: '1px solid var(--border)', cursor: 'pointer',
318
- background: u.role === 'admin' ? 'rgba(37,99,235,0.1)' : u.role === 'editor' ? 'rgba(5,150,105,0.1)' : 'var(--surface-2)',
319
- color: u.role === 'admin' ? '#2563eb' : u.role === 'editor' ? '#059669' : 'var(--muted)',
320
- fontFamily: 'var(--font-sans)', outline: 'none',
321
- opacity: updatingRole === u.id ? 0.5 : 1,
322
- }}
323
- >
324
- <option value="admin">admin</option>
325
- <option value="editor">editor</option>
326
- <option value="viewer">viewer</option>
327
- </select>
328
- {/* Agent write access — only meaningful for editors */}
329
- {u.role === 'editor' && (
330
- <button
331
- onClick={() => toggleExpand(u.id)}
332
- style={{
333
- background: expandedUser === u.id ? 'rgba(59,130,246,0.1)' : 'var(--surface-2)',
334
- border: '1px solid var(--border)', borderRadius: 6,
335
- color: expandedUser === u.id ? 'var(--accent)' : 'var(--muted)',
336
- fontSize: 11, fontWeight: 500, cursor: 'pointer', padding: '3px 10px',
337
- fontFamily: 'var(--font-sans)',
338
- }}
339
- >Agent Access</button>
340
- )}
341
- {u.role === 'viewer' && (
342
- <span title="Viewers are read-only — write access grants only apply to editors" style={{
343
- fontSize: 11, fontWeight: 500, padding: '3px 10px', borderRadius: 6,
344
- border: '1px solid var(--border)', color: 'var(--subtle)',
345
- background: 'var(--surface-2)', opacity: 0.5,
346
- }}>Agent Access</span>
347
- )}
348
- <button onClick={() => remove(u.id, u.username)} style={{
349
- background: 'none', border: 'none', color: '#dc2626',
350
- fontSize: 12, cursor: 'pointer', opacity: 0.6,
351
- fontFamily: 'var(--font-sans)', transition: 'opacity 0.12s',
352
- }}
353
- onMouseEnter={e => (e.currentTarget.style.opacity = '1')}
354
- onMouseLeave={e => (e.currentTarget.style.opacity = '0.6')}
355
- >Delete</button>
356
- </div>
357
-
358
- {/* Expanded agent access panel */}
359
- {expandedUser === u.id && (
360
- <div style={{
361
- margin: '0 16px 12px', padding: '14px 16px', borderRadius: 8,
362
- background: 'var(--surface-2)', border: '1px solid var(--border)',
363
- }}>
364
- <p style={{ margin: '0 0 10px', fontSize: 12, color: 'var(--muted)', fontWeight: 600 }}>
365
- Write access — check agents this user can edit
366
- <span style={{ fontWeight: 400, color: 'var(--subtle)', marginLeft: 6 }}>
367
- (own created agents always have write)
368
- </span>
369
- </p>
370
- {loadingGrants === u.id ? (
371
- <p style={{ fontSize: 12, color: 'var(--subtle)', margin: 0 }}>Loading…</p>
372
- ) : (
373
- <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
374
- {agents.map(a => {
375
- const granted = writeGrants[u.id]?.has(a.id) ?? false;
376
- return (
377
- <label key={a.id} style={{
378
- display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer',
379
- fontSize: 12, color: granted ? 'var(--accent)' : 'var(--muted)',
380
- background: granted ? 'rgba(59,130,246,0.08)' : 'var(--surface)',
381
- border: `1px solid ${granted ? 'rgba(59,130,246,0.3)' : 'var(--border)'}`,
382
- borderRadius: 6, padding: '4px 10px', transition: 'all 0.12s',
383
- }}>
384
- <input
385
- type="checkbox"
386
- checked={granted}
387
- onChange={() => toggleWrite(u.id, a.id, granted)}
388
- style={{ accentColor: 'var(--accent)', cursor: 'pointer' }}
389
- />
390
- {a.name}
391
- </label>
392
- );
393
- })}
394
- {agents.length === 0 && <span style={{ fontSize: 12, color: 'var(--subtle)' }}>No agents yet</span>}
395
- </div>
396
- )}
397
- </div>
398
- )}
399
- </div>
400
- ))}
401
-
402
- {users.length === 0 && (
403
- <div style={{ padding: '20px 16px', textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>
404
- No additional users. Only the superadmin account exists.
405
- </div>
406
- )}
407
- </div>
408
- )}
409
-
410
- {/* Create modal */}
411
- {showForm && (
412
- <Portal>
413
- <div style={{
414
- position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)',
415
- display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9999,
416
- backdropFilter: 'blur(2px)',
417
- }}>
418
- <div style={{
419
- background: '#fff', borderRadius: 14, border: '1px solid var(--border)',
420
- padding: 28, width: 380, boxShadow: 'var(--shadow-lg)',
421
- display: 'flex', flexDirection: 'column', gap: 16,
422
- maxHeight: '90vh', overflow: 'auto',
423
- }}>
424
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
425
- <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600, color: 'var(--text)' }}>New User</h3>
426
- <button onClick={() => { setShowForm(false); setError(''); }}
427
- style={{ background: 'none', border: 'none', color: 'var(--muted)', fontSize: 18, cursor: 'pointer' }}>&times;</button>
428
- </div>
429
- <div>
430
- <label style={{ display: 'block', fontSize: 12, fontWeight: 500, color: 'var(--muted)', marginBottom: 5 }}>Username</label>
431
- <input type="text" value={newUser.username} onChange={e => setNewUser(u => ({ ...u, username: e.target.value }))}
432
- style={{ width: '100%', padding: '8px 12px', borderRadius: 7, border: '1px solid var(--border)', fontSize: 13, outline: 'none', boxSizing: 'border-box', fontFamily: 'var(--font-sans)' }} />
433
- </div>
434
- <div>
435
- <label style={{ display: 'block', fontSize: 12, fontWeight: 500, color: 'var(--muted)', marginBottom: 5 }}>Password</label>
436
- <input type="password" value={newUser.password} onChange={e => setNewUser(u => ({ ...u, password: e.target.value }))}
437
- style={{ width: '100%', padding: '8px 12px', borderRadius: 7, border: '1px solid var(--border)', fontSize: 13, outline: 'none', boxSizing: 'border-box', fontFamily: 'var(--font-sans)' }} />
438
- </div>
439
- <div>
440
- <label style={{ display: 'block', fontSize: 12, fontWeight: 500, color: 'var(--muted)', marginBottom: 5 }}>Role</label>
441
- <select value={newUser.role} onChange={e => setNewUser(u => ({ ...u, role: e.target.value }))}
442
- style={{ width: '100%', padding: '8px 12px', borderRadius: 7, border: '1px solid var(--border)', fontSize: 13, outline: 'none', fontFamily: 'var(--font-sans)', background: '#fff' }}>
443
- <option value="viewer">Viewer — read-only access</option>
444
- <option value="editor">Editor — create/edit agents, jobs, settings</option>
445
- <option value="admin">Admin — full access including user management</option>
446
- </select>
447
- </div>
448
- {error && <div style={{ fontSize: 12, color: '#dc2626', background: 'rgba(220,38,38,0.06)', padding: '6px 10px', borderRadius: 6 }}>{error}</div>}
449
- <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
450
- <button onClick={() => { setShowForm(false); setError(''); }}
451
- style={{ padding: '8px 16px', borderRadius: 7, border: '1px solid var(--border)', background: '#fff', fontSize: 13, cursor: 'pointer', fontFamily: 'var(--font-sans)' }}>Cancel</button>
452
- <button onClick={create} disabled={saving}
453
- style={{ padding: '8px 18px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', fontSize: 13, fontWeight: 500, cursor: 'pointer', fontFamily: 'var(--font-sans)' }}>
454
- {saving ? 'Creating...' : 'Create User'}
455
- </button>
456
- </div>
457
- </div>
458
- </div>
459
- </Portal>
460
- )}
461
- </>
462
- );
463
- }
464
-
465
- // =============================================================================
466
- // Shared UI helpers
467
- // =============================================================================
468
-
469
- function TabBtn({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }) {
470
- return (
471
- <button onClick={onClick} style={{
472
- background: 'none', border: 'none', cursor: 'pointer',
473
- padding: '10px 16px', fontSize: 13,
474
- color: active ? 'var(--text)' : 'var(--muted)',
475
- fontWeight: active ? 600 : 400,
476
- fontFamily: 'var(--font-sans)',
477
- position: 'relative',
478
- transition: 'color 0.15s',
479
- borderBottom: active ? '2px solid var(--accent)' : '2px solid transparent',
480
- marginBottom: -1,
481
- }}>{children}</button>
482
- );
483
- }
484
-
485
- function Section({ title, children }: { title: string; children: React.ReactNode }) {
486
- return (
487
- <div style={{ marginBottom: 22, paddingBottom: 22, borderBottom: '1px solid var(--border)' }}>
488
- <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)', letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 14 }}>{title}</div>
489
- <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>{children}</div>
490
- </div>
491
- );
492
- }
493
-
494
- function Field({ label, value, onChange, onBlur, hint }: {
495
- label: string; value: string; onChange: (v: string) => void; onBlur?: () => void; hint?: string;
496
- }) {
497
- return (
498
- <div>
499
- <label style={{ display: 'block', fontSize: 12, fontWeight: 500, color: 'var(--muted)', marginBottom: 5 }}>{label}</label>
500
- <input type="text" value={value} onChange={e => onChange(e.target.value)}
501
- onBlur={e => { e.currentTarget.style.borderColor = 'var(--border)'; onBlur?.(); }}
502
- style={{
503
- width: '100%', background: 'var(--surface)', border: '1px solid var(--border)',
504
- borderRadius: 7, padding: '8px 11px', color: 'var(--text)',
505
- fontSize: 13, fontFamily: 'var(--font-sans)', outline: 'none',
506
- transition: 'border-color 0.15s', boxSizing: 'border-box',
507
- }}
508
- onFocus={e => (e.currentTarget.style.borderColor = 'var(--accent)')}
509
- />
510
- {hint && <p style={{ margin: '4px 0 0', fontSize: 11, color: 'var(--subtle)' }}>{hint}</p>}
511
- </div>
512
- );
513
- }
514
-
515
- function PrimaryBtn({ children, onClick, loading }: { children: React.ReactNode; onClick?: () => void; loading?: boolean }) {
516
- return (
517
- <button onClick={onClick} disabled={loading} style={{
518
- background: loading ? 'var(--border)' : 'var(--accent)',
519
- color: '#fff', border: 'none', borderRadius: 7,
520
- padding: '8px 18px', fontSize: 13, fontWeight: 500,
521
- cursor: loading ? 'not-allowed' : 'pointer',
522
- fontFamily: 'var(--font-sans)', transition: 'opacity 0.15s',
523
- }}
524
- onMouseEnter={e => { if (!loading) (e.currentTarget as HTMLElement).style.opacity = '0.85'; }}
525
- onMouseLeave={e => { (e.currentTarget as HTMLElement).style.opacity = '1'; }}
526
- >{loading ? 'Saving...' : children}</button>
527
- );
528
- }