@sleep2agi/agent-network-dashboard 0.6.3-preview.56 → 0.6.3-preview.57

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 (718) hide show
  1. package/.next/BUILD_COMMIT +1 -1
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/app-path-routes-manifest.json +9 -0
  4. package/.next/build-manifest.json +3 -3
  5. package/.next/diagnostics/route-bundle-stats.json +145 -95
  6. package/.next/fallback-build-manifest.json +3 -3
  7. package/.next/next-server.js.nft.json +1 -1
  8. package/.next/prerender-manifest.json +75 -19
  9. package/.next/required-server-files.js +4 -4
  10. package/.next/required-server-files.json +4 -4
  11. package/.next/routes-manifest.json +63 -0
  12. package/.next/server/app/_global-error.html +1 -1
  13. package/.next/server/app/_global-error.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  18. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/server/app/_not-found.html +2 -2
  20. package/.next/server/app/_not-found.rsc +14 -14
  21. package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -3
  24. package/.next/server/app/admin/page.js.nft.json +1 -1
  25. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  26. package/.next/server/app/admin.html +2 -2
  27. package/.next/server/app/admin.rsc +16 -16
  28. package/.next/server/app/admin.segments/_full.segment.rsc +16 -16
  29. package/.next/server/app/admin.segments/_tree.segment.rsc +3 -3
  30. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +15 -15
  31. package/.next/server/app/api/anet/host-supervisors/route.js.nft.json +1 -1
  32. package/.next/server/app/api/anet/node-config/route.js +1 -1
  33. package/.next/server/app/api/anet/node-config/route.js.nft.json +1 -1
  34. package/.next/server/app/api/hub/people/route/app-paths-manifest.json +3 -0
  35. package/.next/server/app/api/hub/people/route/build-manifest.json +12 -0
  36. package/.next/server/app/api/hub/people/route/server-reference-manifest.json +4 -0
  37. package/.next/server/app/api/hub/people/route.js +7 -0
  38. package/.next/server/app/api/hub/people/route.js.map +5 -0
  39. package/.next/server/app/api/hub/people/route.js.nft.json +1 -0
  40. package/.next/server/app/api/hub/people/route_client-reference-manifest.js +3 -0
  41. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/app-paths-manifest.json +3 -0
  42. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/build-manifest.json +12 -0
  43. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/server-reference-manifest.json +4 -0
  44. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js +7 -0
  45. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js.map +5 -0
  46. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js.nft.json +1 -0
  47. package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route_client-reference-manifest.js +3 -0
  48. package/.next/server/app/api/hub/requirements/[id]/comments/route/app-paths-manifest.json +3 -0
  49. package/.next/server/app/api/hub/requirements/[id]/comments/route/build-manifest.json +12 -0
  50. package/.next/server/app/api/hub/requirements/[id]/comments/route/server-reference-manifest.json +4 -0
  51. package/.next/server/app/api/hub/requirements/[id]/comments/route.js +7 -0
  52. package/.next/server/app/api/hub/requirements/[id]/comments/route.js.map +5 -0
  53. package/.next/server/app/api/hub/requirements/[id]/comments/route.js.nft.json +1 -0
  54. package/.next/server/app/api/hub/requirements/[id]/comments/route_client-reference-manifest.js +3 -0
  55. package/.next/server/app/api/hub/requirements/[id]/route/app-paths-manifest.json +3 -0
  56. package/.next/server/app/api/hub/requirements/[id]/route/build-manifest.json +12 -0
  57. package/.next/server/app/api/hub/requirements/[id]/route/server-reference-manifest.json +4 -0
  58. package/.next/server/app/api/hub/requirements/[id]/route.js +7 -0
  59. package/.next/server/app/api/hub/requirements/[id]/route.js.map +5 -0
  60. package/.next/server/app/api/hub/requirements/[id]/route.js.nft.json +1 -0
  61. package/.next/server/app/api/hub/requirements/[id]/route_client-reference-manifest.js +3 -0
  62. package/.next/server/app/api/hub/requirements/events/route/app-paths-manifest.json +3 -0
  63. package/.next/server/app/api/hub/requirements/events/route/build-manifest.json +12 -0
  64. package/.next/server/app/api/hub/requirements/events/route/server-reference-manifest.json +4 -0
  65. package/.next/server/app/api/hub/requirements/events/route.js +7 -0
  66. package/.next/server/app/api/hub/requirements/events/route.js.map +5 -0
  67. package/.next/server/app/api/hub/requirements/events/route.js.nft.json +1 -0
  68. package/.next/server/app/api/hub/requirements/events/route_client-reference-manifest.js +3 -0
  69. package/.next/server/app/api/hub/requirements/route/app-paths-manifest.json +3 -0
  70. package/.next/server/app/api/hub/requirements/route/build-manifest.json +12 -0
  71. package/.next/server/app/api/hub/requirements/route/server-reference-manifest.json +4 -0
  72. package/.next/server/app/api/hub/requirements/route.js +7 -0
  73. package/.next/server/app/api/hub/requirements/route.js.map +5 -0
  74. package/.next/server/app/api/hub/requirements/route.js.nft.json +1 -0
  75. package/.next/server/app/api/hub/requirements/route_client-reference-manifest.js +3 -0
  76. package/.next/server/app/index.html +2 -2
  77. package/.next/server/app/index.rsc +16 -16
  78. package/.next/server/app/index.segments/__PAGE__.segment.rsc +15 -15
  79. package/.next/server/app/index.segments/_full.segment.rsc +16 -16
  80. package/.next/server/app/index.segments/_tree.segment.rsc +3 -3
  81. package/.next/server/app/login/page.js.nft.json +1 -1
  82. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  83. package/.next/server/app/login.html +2 -2
  84. package/.next/server/app/login.rsc +16 -16
  85. package/.next/server/app/login.segments/_full.segment.rsc +16 -16
  86. package/.next/server/app/login.segments/_tree.segment.rsc +3 -3
  87. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +15 -15
  88. package/.next/server/app/logs/page.js.nft.json +1 -1
  89. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  90. package/.next/server/app/logs.html +2 -2
  91. package/.next/server/app/logs.rsc +16 -16
  92. package/.next/server/app/logs.segments/_full.segment.rsc +16 -16
  93. package/.next/server/app/logs.segments/_tree.segment.rsc +3 -3
  94. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +15 -15
  95. package/.next/server/app/messages/page.js.nft.json +1 -1
  96. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  97. package/.next/server/app/messages.html +2 -2
  98. package/.next/server/app/messages.rsc +16 -16
  99. package/.next/server/app/messages.segments/_full.segment.rsc +16 -16
  100. package/.next/server/app/messages.segments/_tree.segment.rsc +3 -3
  101. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +15 -15
  102. package/.next/server/app/node/page.js.nft.json +1 -1
  103. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/node.html +2 -2
  105. package/.next/server/app/node.rsc +16 -16
  106. package/.next/server/app/node.segments/_full.segment.rsc +16 -16
  107. package/.next/server/app/node.segments/_tree.segment.rsc +3 -3
  108. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +15 -15
  109. package/.next/server/app/nodes/[alias]/page.js.nft.json +1 -1
  110. package/.next/server/app/nodes/[alias]/page_client-reference-manifest.js +1 -1
  111. package/.next/server/app/nodes/page.js.nft.json +1 -1
  112. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  113. package/.next/server/app/nodes.html +2 -2
  114. package/.next/server/app/nodes.rsc +16 -16
  115. package/.next/server/app/nodes.segments/_full.segment.rsc +16 -16
  116. package/.next/server/app/nodes.segments/_tree.segment.rsc +3 -3
  117. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +15 -15
  118. package/.next/server/app/org/page/app-paths-manifest.json +3 -0
  119. package/.next/server/app/org/page/build-manifest.json +20 -0
  120. package/.next/server/app/org/page/next-font-manifest.json +11 -0
  121. package/.next/server/app/org/page/react-loadable-manifest.json +1 -0
  122. package/.next/server/app/org/page/server-reference-manifest.json +4 -0
  123. package/.next/server/app/org/page.js +13 -0
  124. package/.next/server/app/org/page.js.map +5 -0
  125. package/.next/server/app/org/page.js.nft.json +1 -0
  126. package/.next/server/app/org/page_client-reference-manifest.js +3 -0
  127. package/.next/server/app/org.html +12 -0
  128. package/.next/server/app/org.meta +26 -0
  129. package/.next/server/app/org.rsc +27 -0
  130. package/.next/server/app/org.segments/_full.segment.rsc +27 -0
  131. package/.next/server/app/org.segments/_tree.segment.rsc +5 -0
  132. package/.next/server/app/org.segments/org/__PAGE__.segment.rsc +32 -0
  133. package/.next/server/app/page.js.nft.json +1 -1
  134. package/.next/server/app/page_client-reference-manifest.js +1 -1
  135. package/.next/server/app/providers/page.js.nft.json +1 -1
  136. package/.next/server/app/providers/page_client-reference-manifest.js +1 -1
  137. package/.next/server/app/providers.html +2 -2
  138. package/.next/server/app/providers.rsc +16 -16
  139. package/.next/server/app/providers.segments/_full.segment.rsc +16 -16
  140. package/.next/server/app/providers.segments/_tree.segment.rsc +3 -3
  141. package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +15 -15
  142. package/.next/server/app/requirements/[id]/page/app-paths-manifest.json +3 -0
  143. package/.next/server/app/requirements/[id]/page/build-manifest.json +20 -0
  144. package/.next/server/app/requirements/[id]/page/next-font-manifest.json +11 -0
  145. package/.next/server/app/requirements/[id]/page/react-loadable-manifest.json +1 -0
  146. package/.next/server/app/requirements/[id]/page/server-reference-manifest.json +4 -0
  147. package/.next/server/app/requirements/[id]/page.js +13 -0
  148. package/.next/server/app/requirements/[id]/page.js.map +5 -0
  149. package/.next/server/app/requirements/[id]/page.js.nft.json +1 -0
  150. package/.next/server/app/requirements/[id]/page_client-reference-manifest.js +3 -0
  151. package/.next/server/app/requirements/page/app-paths-manifest.json +3 -0
  152. package/.next/server/app/requirements/page/build-manifest.json +20 -0
  153. package/.next/server/app/requirements/page/next-font-manifest.json +11 -0
  154. package/.next/server/app/requirements/page/react-loadable-manifest.json +1 -0
  155. package/.next/server/app/requirements/page/server-reference-manifest.json +4 -0
  156. package/.next/server/app/requirements/page.js +13 -0
  157. package/.next/server/app/requirements/page.js.map +5 -0
  158. package/.next/server/app/requirements/page.js.nft.json +1 -0
  159. package/.next/server/app/requirements/page_client-reference-manifest.js +3 -0
  160. package/.next/server/app/requirements.html +12 -0
  161. package/.next/server/app/requirements.meta +26 -0
  162. package/.next/server/app/requirements.rsc +27 -0
  163. package/.next/server/app/requirements.segments/_full.segment.rsc +27 -0
  164. package/.next/server/app/requirements.segments/_tree.segment.rsc +5 -0
  165. package/.next/server/app/requirements.segments/requirements/__PAGE__.segment.rsc +32 -0
  166. package/.next/server/app/scheduled-tasks/page.js.nft.json +1 -1
  167. package/.next/server/app/scheduled-tasks/page_client-reference-manifest.js +1 -1
  168. package/.next/server/app/scheduled-tasks.html +2 -2
  169. package/.next/server/app/scheduled-tasks.rsc +16 -16
  170. package/.next/server/app/scheduled-tasks.segments/_full.segment.rsc +16 -16
  171. package/.next/server/app/scheduled-tasks.segments/_tree.segment.rsc +3 -3
  172. package/.next/server/app/scheduled-tasks.segments/scheduled-tasks/__PAGE__.segment.rsc +15 -15
  173. package/.next/server/app/server-logs/page.js.nft.json +1 -1
  174. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  175. package/.next/server/app/server-logs.html +2 -2
  176. package/.next/server/app/server-logs.rsc +16 -16
  177. package/.next/server/app/server-logs.segments/_full.segment.rsc +16 -16
  178. package/.next/server/app/server-logs.segments/_tree.segment.rsc +3 -3
  179. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +15 -15
  180. package/.next/server/app/servers/page.js.nft.json +1 -1
  181. package/.next/server/app/servers/page_client-reference-manifest.js +1 -1
  182. package/.next/server/app/servers.html +2 -2
  183. package/.next/server/app/servers.rsc +16 -16
  184. package/.next/server/app/servers.segments/_full.segment.rsc +16 -16
  185. package/.next/server/app/servers.segments/_tree.segment.rsc +3 -3
  186. package/.next/server/app/servers.segments/servers/__PAGE__.segment.rsc +15 -15
  187. package/.next/server/app/settings/networks/page.js.nft.json +1 -1
  188. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  189. package/.next/server/app/settings/networks.html +2 -2
  190. package/.next/server/app/settings/networks.rsc +16 -16
  191. package/.next/server/app/settings/networks.segments/_full.segment.rsc +16 -16
  192. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +3 -3
  193. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +15 -15
  194. package/.next/server/app/settings/page.js.nft.json +1 -1
  195. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  196. package/.next/server/app/settings/tokens/page.js.nft.json +1 -1
  197. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  198. package/.next/server/app/settings/tokens.html +2 -2
  199. package/.next/server/app/settings/tokens.rsc +16 -16
  200. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +16 -16
  201. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +3 -3
  202. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +15 -15
  203. package/.next/server/app/settings.html +2 -2
  204. package/.next/server/app/settings.rsc +16 -16
  205. package/.next/server/app/settings.segments/_full.segment.rsc +16 -16
  206. package/.next/server/app/settings.segments/_tree.segment.rsc +3 -3
  207. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +15 -15
  208. package/.next/server/app/skillhub/page.js.nft.json +1 -1
  209. package/.next/server/app/skillhub/page_client-reference-manifest.js +1 -1
  210. package/.next/server/app/skillhub.html +2 -2
  211. package/.next/server/app/skillhub.rsc +16 -16
  212. package/.next/server/app/skillhub.segments/_full.segment.rsc +16 -16
  213. package/.next/server/app/skillhub.segments/_tree.segment.rsc +3 -3
  214. package/.next/server/app/skillhub.segments/skillhub/__PAGE__.segment.rsc +15 -15
  215. package/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
  216. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  217. package/.next/server/app/tasks/page.js.nft.json +1 -1
  218. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  219. package/.next/server/app/tasks.html +2 -2
  220. package/.next/server/app/tasks.rsc +16 -16
  221. package/.next/server/app/tasks.segments/_full.segment.rsc +16 -16
  222. package/.next/server/app/tasks.segments/_tree.segment.rsc +3 -3
  223. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +15 -15
  224. package/.next/server/app-paths-manifest.json +9 -0
  225. package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_checklist_[itemId]_route_actions_05mpe5a.js +3 -0
  226. package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_checklist_[itemId]_route_actions_05mpe5a.js.map +1 -0
  227. package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_comments_route_actions_1lv4qr1.js +3 -0
  228. package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_comments_route_actions_1lv4qr1.js.map +1 -0
  229. package/.next/server/chunks/[root-of-the-server]__0-wvy_a._.js +1 -1
  230. package/.next/server/chunks/[root-of-the-server]__0-wvy_a._.js.map +1 -1
  231. package/.next/server/chunks/[root-of-the-server]__053z4wp._.js +3 -0
  232. package/.next/server/chunks/[root-of-the-server]__053z4wp._.js.map +1 -0
  233. package/.next/server/chunks/[root-of-the-server]__0if0bw1._.js +3 -0
  234. package/.next/server/chunks/[root-of-the-server]__0if0bw1._.js.map +1 -0
  235. package/.next/server/chunks/[root-of-the-server]__0liwkmx._.js +1 -1
  236. package/.next/server/chunks/[root-of-the-server]__0liwkmx._.js.map +1 -1
  237. package/.next/server/chunks/[root-of-the-server]__0q9xwca._.js +3 -0
  238. package/.next/server/chunks/[root-of-the-server]__0q9xwca._.js.map +1 -0
  239. package/.next/server/chunks/[root-of-the-server]__1941b2h._.js +3 -0
  240. package/.next/server/chunks/[root-of-the-server]__1941b2h._.js.map +1 -0
  241. package/.next/server/chunks/[root-of-the-server]__1_rzyvn._.js +3 -0
  242. package/.next/server/chunks/[root-of-the-server]__1_rzyvn._.js.map +1 -0
  243. package/.next/server/chunks/[root-of-the-server]__1vua9gf._.js +3 -0
  244. package/.next/server/chunks/[root-of-the-server]__1vua9gf._.js.map +1 -0
  245. package/.next/server/chunks/_05lpz54._.js +1 -1
  246. package/.next/server/chunks/_05lpz54._.js.map +1 -1
  247. package/.next/server/chunks/_next-internal_server_app_api_hub_people_route_actions_01pw78e.js +3 -0
  248. package/.next/server/chunks/_next-internal_server_app_api_hub_people_route_actions_01pw78e.js.map +1 -0
  249. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_[id]_route_actions_1jkq5c6.js +3 -0
  250. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_[id]_route_actions_1jkq5c6.js.map +1 -0
  251. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_events_route_actions_1ypnpu5.js +3 -0
  252. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_events_route_actions_1ypnpu5.js.map +1 -0
  253. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_route_actions_1lyeno6.js +3 -0
  254. package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_route_actions_1lyeno6.js.map +1 -0
  255. package/.next/server/chunks/ssr/[root-of-the-server]__0-94ipy._.js +3 -0
  256. package/.next/server/chunks/ssr/[root-of-the-server]__0-94ipy._.js.map +1 -0
  257. package/.next/server/chunks/ssr/[root-of-the-server]__09n7eih._.js +3 -0
  258. package/.next/server/chunks/ssr/[root-of-the-server]__09n7eih._.js.map +1 -0
  259. package/.next/server/chunks/ssr/[root-of-the-server]__0ol09h3._.js +3 -0
  260. package/.next/server/chunks/ssr/[root-of-the-server]__0ol09h3._.js.map +1 -0
  261. package/.next/server/chunks/ssr/[root-of-the-server]__14k36ti._.js +3 -0
  262. package/.next/server/chunks/ssr/[root-of-the-server]__14k36ti._.js.map +1 -0
  263. package/.next/server/chunks/ssr/[root-of-the-server]__1bn1jjm._.js +3 -0
  264. package/.next/server/chunks/ssr/[root-of-the-server]__1bn1jjm._.js.map +1 -0
  265. package/.next/server/chunks/ssr/[root-of-the-server]__1ovdbox._.js +1 -1
  266. package/.next/server/chunks/ssr/[root-of-the-server]__1ovdbox._.js.map +1 -1
  267. package/.next/server/chunks/ssr/_0q4m25o._.js +0 -0
  268. package/.next/server/chunks/ssr/_0q4m25o._.js.map +1 -1
  269. package/.next/server/chunks/ssr/_1z1o6o3._.js +0 -0
  270. package/.next/server/chunks/ssr/_1z1o6o3._.js.map +1 -1
  271. package/.next/server/chunks/ssr/_next-internal_server_app_org_page_actions_0hbcef1.js +3 -0
  272. package/.next/server/chunks/ssr/_next-internal_server_app_org_page_actions_0hbcef1.js.map +1 -0
  273. package/.next/server/chunks/ssr/_next-internal_server_app_requirements_[id]_page_actions_1wjoy4l.js +3 -0
  274. package/.next/server/chunks/ssr/_next-internal_server_app_requirements_[id]_page_actions_1wjoy4l.js.map +1 -0
  275. package/.next/server/chunks/ssr/_next-internal_server_app_requirements_page_actions_0x9m0gy.js +3 -0
  276. package/.next/server/chunks/ssr/_next-internal_server_app_requirements_page_actions_0x9m0gy.js.map +1 -0
  277. package/.next/server/chunks/ssr/app_05mfyco._.js +3 -0
  278. package/.next/server/chunks/ssr/app_05mfyco._.js.map +1 -0
  279. package/.next/server/chunks/ssr/{app_0_s8u96._.js → app_07bzc6w._.js} +1 -1
  280. package/.next/server/chunks/ssr/app_099f0wg._.js +3 -0
  281. package/.next/server/chunks/ssr/app_099f0wg._.js.map +1 -0
  282. package/.next/server/chunks/ssr/{app_1oxcq68._.js → app_0g7oz9w._.js} +1 -1
  283. package/.next/server/chunks/ssr/app_0iz553k._.js +1 -1
  284. package/.next/server/chunks/ssr/app_0iz553k._.js.map +1 -1
  285. package/.next/server/chunks/ssr/app_0los-eu._.js +1 -1
  286. package/.next/server/chunks/ssr/app_0los-eu._.js.map +1 -1
  287. package/.next/server/chunks/ssr/{app_0x7s72b._.js → app_0tt2ueo._.js} +1 -1
  288. package/.next/server/chunks/ssr/{app_081zy6c._.js → app_0ugqkd7._.js} +1 -1
  289. package/.next/server/chunks/ssr/app_1auk3il._.js +11 -0
  290. package/.next/server/chunks/ssr/app_1auk3il._.js.map +1 -0
  291. package/.next/server/chunks/ssr/{app_0o4bxq0._.js → app_1e91uc-._.js} +1 -1
  292. package/.next/server/chunks/ssr/{app_1psh956._.js → app_1f96aq_._.js} +1 -1
  293. package/.next/server/chunks/ssr/app_1rma_8a._.js +11 -0
  294. package/.next/server/chunks/ssr/app_1rma_8a._.js.map +1 -0
  295. package/.next/server/chunks/ssr/{app_0_dhiwi._.js → app_1ua57bx._.js} +1 -1
  296. package/.next/server/chunks/ssr/app_components_04a31va._.js +1 -1
  297. package/.next/server/chunks/ssr/app_components_04a31va._.js.map +1 -1
  298. package/.next/server/chunks/ssr/{app_lib_10o69j_._.js → app_lib_20-pe_0._.js} +2 -2
  299. package/.next/server/chunks/ssr/{app_lib_10o69j_._.js.map → app_lib_20-pe_0._.js.map} +1 -1
  300. package/.next/server/chunks/ssr/app_nodes_NodesView_tsx_1w6_d8p._.js +2 -2
  301. package/.next/server/chunks/ssr/app_nodes_NodesView_tsx_1w6_d8p._.js.map +1 -1
  302. package/.next/server/chunks/ssr/app_page_tsx_0pxmutw._.js +1 -1
  303. package/.next/server/chunks/ssr/app_page_tsx_0pxmutw._.js.map +1 -1
  304. package/.next/server/chunks/ssr/app_scheduled-tasks_page_tsx_0xs70_6._.js +1 -1
  305. package/.next/server/chunks/ssr/app_scheduled-tasks_page_tsx_0xs70_6._.js.map +1 -1
  306. package/.next/server/chunks/ssr/app_tasks_TasksView_tsx_068vqml._.js +1 -1
  307. package/.next/server/chunks/ssr/app_tasks_TasksView_tsx_068vqml._.js.map +1 -1
  308. package/.next/server/functions-config-manifest.json +4 -0
  309. package/.next/server/middleware-build-manifest.js +3 -3
  310. package/.next/server/middleware.js.nft.json +1 -1
  311. package/.next/server/next-font-manifest.js +1 -1
  312. package/.next/server/next-font-manifest.json +12 -0
  313. package/.next/server/pages/404.html +2 -2
  314. package/.next/server/pages/500.html +1 -1
  315. package/.next/server/prefetch-hints.json +28 -0
  316. package/.next/server/server-reference-manifest.js +1 -1
  317. package/.next/server/server-reference-manifest.json +1 -1
  318. package/.next/static/{trj9RsCWuEDMfq9BuoKfl → _HZB6K84VKNaxf1K7dqqj}/_clientMiddlewareManifest.js +4 -0
  319. package/.next/static/chunks/{27b9kqyo7bmdr.js → 08-obrj2goweb.js} +2 -2
  320. package/.next/static/chunks/{0agh8mvmpke4j.js → 0cuzbmf4k1kgl.js} +1 -1
  321. package/.next/static/chunks/0fih4pzed1syn.js +9 -0
  322. package/.next/static/chunks/0iiu4-g5k8jcq.js +1 -0
  323. package/.next/static/chunks/{37booeyruo9_l.js → 0iz44n632kw4w.js} +1 -1
  324. package/.next/static/chunks/0jt-1caejz1jv.js +1 -0
  325. package/.next/static/chunks/0k-4980o5t7_r.css +1 -0
  326. package/.next/static/chunks/114pblaedlrqs.js +1 -0
  327. package/.next/static/chunks/1tcaw8g6u6o-4.js +1 -0
  328. package/.next/static/chunks/1v5-qgib9884o.js +0 -0
  329. package/.next/static/chunks/{02303d1rbqx74.js → 2-x9r-1t3c1mn.js} +1 -1
  330. package/.next/static/chunks/{28o3ssg0_q2n-.js → 21djd6ixldlx0.js} +1 -1
  331. package/.next/static/chunks/2anlzel60my8y.js +2 -0
  332. package/.next/static/chunks/{3jxk7q1jxyvol.js → 2juzvtg9ne4yt.js} +1 -1
  333. package/.next/static/chunks/3cb3_kcec7bms.js +1 -0
  334. package/.next/static/chunks/{233p45nuh4m5b.css → 3d-1vk5hzu5rq.css} +2 -2
  335. package/.next/static/chunks/3shtxab8cmux9.js +1 -0
  336. package/.next/static/chunks/3u059pjgl4gcw.js +1 -0
  337. package/.next/trace +2 -2
  338. package/.next/trace-build +1 -1
  339. package/.next/types/routes.d.ts +11 -2
  340. package/.next/types/validator.ts +81 -0
  341. package/.vercel/.env.development.local +2 -0
  342. package/.vercel/.env.production.local +25 -0
  343. package/.vercel/README.txt +11 -0
  344. package/.vercel/output/builds.json +23 -0
  345. package/.vercel/output/config.json +489 -0
  346. package/.vercel/output/diagnostics/build-diagnostics.json +6 -0
  347. package/.vercel/output/diagnostics/cli_traces.json +1 -0
  348. package/.vercel/output/diagnostics/framework.json +1 -0
  349. package/.vercel/output/diagnostics/route-bundle-stats.json +245 -0
  350. package/.vercel/output/diagnostics/trace +2 -0
  351. package/.vercel/output/diagnostics/trace-build +1 -0
  352. package/.vercel/output/diagnostics/turbopack +0 -0
  353. package/.vercel/output/functions/_global-error.prerender-config.json +38 -0
  354. package/.vercel/output/functions/_global-error.prerender-fallback.html +1 -0
  355. package/.vercel/output/functions/_global-error.rsc.func/.next/routes-manifest.json +1 -0
  356. package/.vercel/output/functions/_global-error.rsc.func/.next/server/app-paths-manifest.json +1 -0
  357. package/.vercel/output/functions/_global-error.rsc.func/.next/server/pages-manifest.json +1 -0
  358. package/.vercel/output/functions/_global-error.rsc.func/.vc-config.json +807 -0
  359. package/.vercel/output/functions/_global-error.rsc.func/___next_launcher.cjs +68 -0
  360. package/.vercel/output/functions/_global-error.rsc.prerender-config.json +38 -0
  361. package/.vercel/output/functions/_global-error.rsc.prerender-fallback.rsc +15 -0
  362. package/.vercel/output/functions/_global-error.segments/__PAGE__.segment.rsc.prerender-config.json +28 -0
  363. package/.vercel/output/functions/_global-error.segments/__PAGE__.segment.rsc.prerender-fallback.rsc +5 -0
  364. package/.vercel/output/functions/_global-error.segments/_full.segment.rsc.prerender-config.json +28 -0
  365. package/.vercel/output/functions/_global-error.segments/_full.segment.rsc.prerender-fallback.rsc +15 -0
  366. package/.vercel/output/functions/_global-error.segments/_head.segment.rsc.prerender-config.json +28 -0
  367. package/.vercel/output/functions/_global-error.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  368. package/.vercel/output/functions/_global-error.segments/_index.segment.rsc.prerender-config.json +28 -0
  369. package/.vercel/output/functions/_global-error.segments/_index.segment.rsc.prerender-fallback.rsc +5 -0
  370. package/.vercel/output/functions/_global-error.segments/_tree.segment.rsc.prerender-config.json +28 -0
  371. package/.vercel/output/functions/_global-error.segments/_tree.segment.rsc.prerender-fallback.rsc +1 -0
  372. package/.vercel/output/functions/_middleware.func/.vc-config.json +107 -0
  373. package/.vercel/output/functions/_middleware.func/___next_launcher.cjs +135 -0
  374. package/.vercel/output/functions/_not-found.prerender-config.json +38 -0
  375. package/.vercel/output/functions/_not-found.prerender-fallback.html +12 -0
  376. package/.vercel/output/functions/_not-found.rsc.prerender-config.json +38 -0
  377. package/.vercel/output/functions/_not-found.rsc.prerender-fallback.rsc +21 -0
  378. package/.vercel/output/functions/_not-found.segments/_full.segment.rsc.prerender-config.json +28 -0
  379. package/.vercel/output/functions/_not-found.segments/_full.segment.rsc.prerender-fallback.rsc +21 -0
  380. package/.vercel/output/functions/_not-found.segments/_head.segment.rsc.prerender-config.json +28 -0
  381. package/.vercel/output/functions/_not-found.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  382. package/.vercel/output/functions/_not-found.segments/_index.segment.rsc.prerender-config.json +28 -0
  383. package/.vercel/output/functions/_not-found.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  384. package/.vercel/output/functions/_not-found.segments/_not-found/__PAGE__.segment.rsc.prerender-config.json +28 -0
  385. package/.vercel/output/functions/_not-found.segments/_not-found/__PAGE__.segment.rsc.prerender-fallback.rsc +5 -0
  386. package/.vercel/output/functions/_not-found.segments/_not-found.segment.rsc.prerender-config.json +28 -0
  387. package/.vercel/output/functions/_not-found.segments/_not-found.segment.rsc.prerender-fallback.rsc +5 -0
  388. package/.vercel/output/functions/_not-found.segments/_tree.segment.rsc.prerender-config.json +28 -0
  389. package/.vercel/output/functions/_not-found.segments/_tree.segment.rsc.prerender-fallback.rsc +3 -0
  390. package/.vercel/output/functions/admin.prerender-config.json +37 -0
  391. package/.vercel/output/functions/admin.prerender-fallback.html +12 -0
  392. package/.vercel/output/functions/admin.rsc.prerender-config.json +38 -0
  393. package/.vercel/output/functions/admin.rsc.prerender-fallback.rsc +27 -0
  394. package/.vercel/output/functions/admin.segments/_full.segment.rsc.prerender-config.json +28 -0
  395. package/.vercel/output/functions/admin.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  396. package/.vercel/output/functions/admin.segments/_head.segment.rsc.prerender-config.json +28 -0
  397. package/.vercel/output/functions/admin.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  398. package/.vercel/output/functions/admin.segments/_index.segment.rsc.prerender-config.json +28 -0
  399. package/.vercel/output/functions/admin.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  400. package/.vercel/output/functions/admin.segments/_tree.segment.rsc.prerender-config.json +28 -0
  401. package/.vercel/output/functions/admin.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  402. package/.vercel/output/functions/admin.segments/admin/__PAGE__.segment.rsc.prerender-config.json +28 -0
  403. package/.vercel/output/functions/admin.segments/admin/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  404. package/.vercel/output/functions/admin.segments/admin.segment.rsc.prerender-config.json +28 -0
  405. package/.vercel/output/functions/admin.segments/admin.segment.rsc.prerender-fallback.rsc +5 -0
  406. package/.vercel/output/functions/api/anet/config.func/.next/routes-manifest.json +1 -0
  407. package/.vercel/output/functions/api/anet/config.func/.next/server/app-paths-manifest.json +1 -0
  408. package/.vercel/output/functions/api/anet/config.func/.next/server/pages-manifest.json +1 -0
  409. package/.vercel/output/functions/api/anet/config.func/.vc-config.json +818 -0
  410. package/.vercel/output/functions/api/anet/config.func/___next_launcher.cjs +68 -0
  411. package/.vercel/output/functions/index.prerender-config.json +38 -0
  412. package/.vercel/output/functions/index.prerender-fallback.html +12 -0
  413. package/.vercel/output/functions/index.rsc.prerender-config.json +38 -0
  414. package/.vercel/output/functions/index.rsc.prerender-fallback.rsc +25 -0
  415. package/.vercel/output/functions/index.segments/__PAGE__.segment.rsc.prerender-config.json +28 -0
  416. package/.vercel/output/functions/index.segments/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  417. package/.vercel/output/functions/index.segments/_full.segment.rsc.prerender-config.json +28 -0
  418. package/.vercel/output/functions/index.segments/_full.segment.rsc.prerender-fallback.rsc +25 -0
  419. package/.vercel/output/functions/index.segments/_head.segment.rsc.prerender-config.json +28 -0
  420. package/.vercel/output/functions/index.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  421. package/.vercel/output/functions/index.segments/_index.segment.rsc.prerender-config.json +28 -0
  422. package/.vercel/output/functions/index.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  423. package/.vercel/output/functions/index.segments/_tree.segment.rsc.prerender-config.json +28 -0
  424. package/.vercel/output/functions/index.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  425. package/.vercel/output/functions/login.prerender-config.json +37 -0
  426. package/.vercel/output/functions/login.prerender-fallback.html +6 -0
  427. package/.vercel/output/functions/login.rsc.prerender-config.json +38 -0
  428. package/.vercel/output/functions/login.rsc.prerender-fallback.rsc +27 -0
  429. package/.vercel/output/functions/login.segments/_full.segment.rsc.prerender-config.json +28 -0
  430. package/.vercel/output/functions/login.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  431. package/.vercel/output/functions/login.segments/_head.segment.rsc.prerender-config.json +28 -0
  432. package/.vercel/output/functions/login.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  433. package/.vercel/output/functions/login.segments/_index.segment.rsc.prerender-config.json +28 -0
  434. package/.vercel/output/functions/login.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  435. package/.vercel/output/functions/login.segments/_tree.segment.rsc.prerender-config.json +28 -0
  436. package/.vercel/output/functions/login.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  437. package/.vercel/output/functions/login.segments/login/__PAGE__.segment.rsc.prerender-config.json +28 -0
  438. package/.vercel/output/functions/login.segments/login/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  439. package/.vercel/output/functions/login.segments/login.segment.rsc.prerender-config.json +28 -0
  440. package/.vercel/output/functions/login.segments/login.segment.rsc.prerender-fallback.rsc +5 -0
  441. package/.vercel/output/functions/logs.prerender-config.json +37 -0
  442. package/.vercel/output/functions/logs.prerender-fallback.html +12 -0
  443. package/.vercel/output/functions/logs.rsc.prerender-config.json +38 -0
  444. package/.vercel/output/functions/logs.rsc.prerender-fallback.rsc +27 -0
  445. package/.vercel/output/functions/logs.segments/_full.segment.rsc.prerender-config.json +28 -0
  446. package/.vercel/output/functions/logs.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  447. package/.vercel/output/functions/logs.segments/_head.segment.rsc.prerender-config.json +28 -0
  448. package/.vercel/output/functions/logs.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  449. package/.vercel/output/functions/logs.segments/_index.segment.rsc.prerender-config.json +28 -0
  450. package/.vercel/output/functions/logs.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  451. package/.vercel/output/functions/logs.segments/_tree.segment.rsc.prerender-config.json +28 -0
  452. package/.vercel/output/functions/logs.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  453. package/.vercel/output/functions/logs.segments/logs/__PAGE__.segment.rsc.prerender-config.json +28 -0
  454. package/.vercel/output/functions/logs.segments/logs/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  455. package/.vercel/output/functions/logs.segments/logs.segment.rsc.prerender-config.json +28 -0
  456. package/.vercel/output/functions/logs.segments/logs.segment.rsc.prerender-fallback.rsc +5 -0
  457. package/.vercel/output/functions/manifest.webmanifest.func/.next/routes-manifest.json +1 -0
  458. package/.vercel/output/functions/manifest.webmanifest.func/.next/server/app-paths-manifest.json +1 -0
  459. package/.vercel/output/functions/manifest.webmanifest.func/.next/server/pages-manifest.json +1 -0
  460. package/.vercel/output/functions/manifest.webmanifest.func/.vc-config.json +715 -0
  461. package/.vercel/output/functions/manifest.webmanifest.func/___next_launcher.cjs +68 -0
  462. package/.vercel/output/functions/manifest.webmanifest.prerender-config.json +38 -0
  463. package/.vercel/output/functions/manifest.webmanifest.prerender-fallback.body +1 -0
  464. package/.vercel/output/functions/messages.prerender-config.json +37 -0
  465. package/.vercel/output/functions/messages.prerender-fallback.html +12 -0
  466. package/.vercel/output/functions/messages.rsc.prerender-config.json +38 -0
  467. package/.vercel/output/functions/messages.rsc.prerender-fallback.rsc +27 -0
  468. package/.vercel/output/functions/messages.segments/_full.segment.rsc.prerender-config.json +28 -0
  469. package/.vercel/output/functions/messages.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  470. package/.vercel/output/functions/messages.segments/_head.segment.rsc.prerender-config.json +28 -0
  471. package/.vercel/output/functions/messages.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  472. package/.vercel/output/functions/messages.segments/_index.segment.rsc.prerender-config.json +28 -0
  473. package/.vercel/output/functions/messages.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  474. package/.vercel/output/functions/messages.segments/_tree.segment.rsc.prerender-config.json +28 -0
  475. package/.vercel/output/functions/messages.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  476. package/.vercel/output/functions/messages.segments/messages/__PAGE__.segment.rsc.prerender-config.json +28 -0
  477. package/.vercel/output/functions/messages.segments/messages/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  478. package/.vercel/output/functions/messages.segments/messages.segment.rsc.prerender-config.json +28 -0
  479. package/.vercel/output/functions/messages.segments/messages.segment.rsc.prerender-fallback.rsc +5 -0
  480. package/.vercel/output/functions/node.prerender-config.json +37 -0
  481. package/.vercel/output/functions/node.prerender-fallback.html +12 -0
  482. package/.vercel/output/functions/node.rsc.prerender-config.json +38 -0
  483. package/.vercel/output/functions/node.rsc.prerender-fallback.rsc +27 -0
  484. package/.vercel/output/functions/node.segments/_full.segment.rsc.prerender-config.json +28 -0
  485. package/.vercel/output/functions/node.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  486. package/.vercel/output/functions/node.segments/_head.segment.rsc.prerender-config.json +28 -0
  487. package/.vercel/output/functions/node.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  488. package/.vercel/output/functions/node.segments/_index.segment.rsc.prerender-config.json +28 -0
  489. package/.vercel/output/functions/node.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  490. package/.vercel/output/functions/node.segments/_tree.segment.rsc.prerender-config.json +28 -0
  491. package/.vercel/output/functions/node.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  492. package/.vercel/output/functions/node.segments/node/__PAGE__.segment.rsc.prerender-config.json +28 -0
  493. package/.vercel/output/functions/node.segments/node/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  494. package/.vercel/output/functions/node.segments/node.segment.rsc.prerender-config.json +28 -0
  495. package/.vercel/output/functions/node.segments/node.segment.rsc.prerender-fallback.rsc +5 -0
  496. package/.vercel/output/functions/nodes.prerender-config.json +37 -0
  497. package/.vercel/output/functions/nodes.prerender-fallback.html +12 -0
  498. package/.vercel/output/functions/nodes.rsc.prerender-config.json +38 -0
  499. package/.vercel/output/functions/nodes.rsc.prerender-fallback.rsc +27 -0
  500. package/.vercel/output/functions/nodes.segments/_full.segment.rsc.prerender-config.json +28 -0
  501. package/.vercel/output/functions/nodes.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  502. package/.vercel/output/functions/nodes.segments/_head.segment.rsc.prerender-config.json +28 -0
  503. package/.vercel/output/functions/nodes.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  504. package/.vercel/output/functions/nodes.segments/_index.segment.rsc.prerender-config.json +28 -0
  505. package/.vercel/output/functions/nodes.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  506. package/.vercel/output/functions/nodes.segments/_tree.segment.rsc.prerender-config.json +28 -0
  507. package/.vercel/output/functions/nodes.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  508. package/.vercel/output/functions/nodes.segments/nodes/__PAGE__.segment.rsc.prerender-config.json +28 -0
  509. package/.vercel/output/functions/nodes.segments/nodes/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  510. package/.vercel/output/functions/nodes.segments/nodes.segment.rsc.prerender-config.json +28 -0
  511. package/.vercel/output/functions/nodes.segments/nodes.segment.rsc.prerender-fallback.rsc +5 -0
  512. package/.vercel/output/functions/server-logs.prerender-config.json +37 -0
  513. package/.vercel/output/functions/server-logs.prerender-fallback.html +12 -0
  514. package/.vercel/output/functions/server-logs.rsc.prerender-config.json +38 -0
  515. package/.vercel/output/functions/server-logs.rsc.prerender-fallback.rsc +27 -0
  516. package/.vercel/output/functions/server-logs.segments/_full.segment.rsc.prerender-config.json +28 -0
  517. package/.vercel/output/functions/server-logs.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  518. package/.vercel/output/functions/server-logs.segments/_head.segment.rsc.prerender-config.json +28 -0
  519. package/.vercel/output/functions/server-logs.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  520. package/.vercel/output/functions/server-logs.segments/_index.segment.rsc.prerender-config.json +28 -0
  521. package/.vercel/output/functions/server-logs.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  522. package/.vercel/output/functions/server-logs.segments/_tree.segment.rsc.prerender-config.json +28 -0
  523. package/.vercel/output/functions/server-logs.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  524. package/.vercel/output/functions/server-logs.segments/server-logs/__PAGE__.segment.rsc.prerender-config.json +28 -0
  525. package/.vercel/output/functions/server-logs.segments/server-logs/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  526. package/.vercel/output/functions/server-logs.segments/server-logs.segment.rsc.prerender-config.json +28 -0
  527. package/.vercel/output/functions/server-logs.segments/server-logs.segment.rsc.prerender-fallback.rsc +5 -0
  528. package/.vercel/output/functions/servers.prerender-config.json +37 -0
  529. package/.vercel/output/functions/servers.prerender-fallback.html +12 -0
  530. package/.vercel/output/functions/servers.rsc.prerender-config.json +38 -0
  531. package/.vercel/output/functions/servers.rsc.prerender-fallback.rsc +27 -0
  532. package/.vercel/output/functions/servers.segments/_full.segment.rsc.prerender-config.json +28 -0
  533. package/.vercel/output/functions/servers.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  534. package/.vercel/output/functions/servers.segments/_head.segment.rsc.prerender-config.json +28 -0
  535. package/.vercel/output/functions/servers.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  536. package/.vercel/output/functions/servers.segments/_index.segment.rsc.prerender-config.json +28 -0
  537. package/.vercel/output/functions/servers.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  538. package/.vercel/output/functions/servers.segments/_tree.segment.rsc.prerender-config.json +28 -0
  539. package/.vercel/output/functions/servers.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  540. package/.vercel/output/functions/servers.segments/servers/__PAGE__.segment.rsc.prerender-config.json +28 -0
  541. package/.vercel/output/functions/servers.segments/servers/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  542. package/.vercel/output/functions/servers.segments/servers.segment.rsc.prerender-config.json +28 -0
  543. package/.vercel/output/functions/servers.segments/servers.segment.rsc.prerender-fallback.rsc +5 -0
  544. package/.vercel/output/functions/settings/networks.prerender-config.json +37 -0
  545. package/.vercel/output/functions/settings/networks.prerender-fallback.html +12 -0
  546. package/.vercel/output/functions/settings/networks.rsc.prerender-config.json +38 -0
  547. package/.vercel/output/functions/settings/networks.rsc.prerender-fallback.rsc +27 -0
  548. package/.vercel/output/functions/settings/networks.segments/_full.segment.rsc.prerender-config.json +28 -0
  549. package/.vercel/output/functions/settings/networks.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  550. package/.vercel/output/functions/settings/networks.segments/_head.segment.rsc.prerender-config.json +28 -0
  551. package/.vercel/output/functions/settings/networks.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  552. package/.vercel/output/functions/settings/networks.segments/_index.segment.rsc.prerender-config.json +28 -0
  553. package/.vercel/output/functions/settings/networks.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  554. package/.vercel/output/functions/settings/networks.segments/_tree.segment.rsc.prerender-config.json +28 -0
  555. package/.vercel/output/functions/settings/networks.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  556. package/.vercel/output/functions/settings/networks.segments/settings/networks/__PAGE__.segment.rsc.prerender-config.json +28 -0
  557. package/.vercel/output/functions/settings/networks.segments/settings/networks/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  558. package/.vercel/output/functions/settings/networks.segments/settings/networks.segment.rsc.prerender-config.json +28 -0
  559. package/.vercel/output/functions/settings/networks.segments/settings/networks.segment.rsc.prerender-fallback.rsc +5 -0
  560. package/.vercel/output/functions/settings/networks.segments/settings.segment.rsc.prerender-config.json +28 -0
  561. package/.vercel/output/functions/settings/networks.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
  562. package/.vercel/output/functions/settings/tokens.prerender-config.json +37 -0
  563. package/.vercel/output/functions/settings/tokens.prerender-fallback.html +12 -0
  564. package/.vercel/output/functions/settings/tokens.rsc.prerender-config.json +38 -0
  565. package/.vercel/output/functions/settings/tokens.rsc.prerender-fallback.rsc +27 -0
  566. package/.vercel/output/functions/settings/tokens.segments/_full.segment.rsc.prerender-config.json +28 -0
  567. package/.vercel/output/functions/settings/tokens.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  568. package/.vercel/output/functions/settings/tokens.segments/_head.segment.rsc.prerender-config.json +28 -0
  569. package/.vercel/output/functions/settings/tokens.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  570. package/.vercel/output/functions/settings/tokens.segments/_index.segment.rsc.prerender-config.json +28 -0
  571. package/.vercel/output/functions/settings/tokens.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  572. package/.vercel/output/functions/settings/tokens.segments/_tree.segment.rsc.prerender-config.json +28 -0
  573. package/.vercel/output/functions/settings/tokens.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  574. package/.vercel/output/functions/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc.prerender-config.json +28 -0
  575. package/.vercel/output/functions/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  576. package/.vercel/output/functions/settings/tokens.segments/settings/tokens.segment.rsc.prerender-config.json +28 -0
  577. package/.vercel/output/functions/settings/tokens.segments/settings/tokens.segment.rsc.prerender-fallback.rsc +5 -0
  578. package/.vercel/output/functions/settings/tokens.segments/settings.segment.rsc.prerender-config.json +28 -0
  579. package/.vercel/output/functions/settings/tokens.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
  580. package/.vercel/output/functions/settings.prerender-config.json +37 -0
  581. package/.vercel/output/functions/settings.prerender-fallback.html +12 -0
  582. package/.vercel/output/functions/settings.rsc.prerender-config.json +38 -0
  583. package/.vercel/output/functions/settings.rsc.prerender-fallback.rsc +27 -0
  584. package/.vercel/output/functions/settings.segments/_full.segment.rsc.prerender-config.json +28 -0
  585. package/.vercel/output/functions/settings.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  586. package/.vercel/output/functions/settings.segments/_head.segment.rsc.prerender-config.json +28 -0
  587. package/.vercel/output/functions/settings.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  588. package/.vercel/output/functions/settings.segments/_index.segment.rsc.prerender-config.json +28 -0
  589. package/.vercel/output/functions/settings.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  590. package/.vercel/output/functions/settings.segments/_tree.segment.rsc.prerender-config.json +28 -0
  591. package/.vercel/output/functions/settings.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  592. package/.vercel/output/functions/settings.segments/settings/__PAGE__.segment.rsc.prerender-config.json +28 -0
  593. package/.vercel/output/functions/settings.segments/settings/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  594. package/.vercel/output/functions/settings.segments/settings.segment.rsc.prerender-config.json +28 -0
  595. package/.vercel/output/functions/settings.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
  596. package/.vercel/output/functions/tasks/[id].func/.next/routes-manifest.json +1 -0
  597. package/.vercel/output/functions/tasks/[id].func/.next/server/app-paths-manifest.json +1 -0
  598. package/.vercel/output/functions/tasks/[id].func/.next/server/pages-manifest.json +1 -0
  599. package/.vercel/output/functions/tasks/[id].func/.vc-config.json +713 -0
  600. package/.vercel/output/functions/tasks/[id].func/___next_launcher.cjs +68 -0
  601. package/.vercel/output/functions/tasks.prerender-config.json +37 -0
  602. package/.vercel/output/functions/tasks.prerender-fallback.html +12 -0
  603. package/.vercel/output/functions/tasks.rsc.prerender-config.json +38 -0
  604. package/.vercel/output/functions/tasks.rsc.prerender-fallback.rsc +27 -0
  605. package/.vercel/output/functions/tasks.segments/_full.segment.rsc.prerender-config.json +28 -0
  606. package/.vercel/output/functions/tasks.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
  607. package/.vercel/output/functions/tasks.segments/_head.segment.rsc.prerender-config.json +28 -0
  608. package/.vercel/output/functions/tasks.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
  609. package/.vercel/output/functions/tasks.segments/_index.segment.rsc.prerender-config.json +28 -0
  610. package/.vercel/output/functions/tasks.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
  611. package/.vercel/output/functions/tasks.segments/_tree.segment.rsc.prerender-config.json +28 -0
  612. package/.vercel/output/functions/tasks.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
  613. package/.vercel/output/functions/tasks.segments/tasks/__PAGE__.segment.rsc.prerender-config.json +28 -0
  614. package/.vercel/output/functions/tasks.segments/tasks/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
  615. package/.vercel/output/functions/tasks.segments/tasks.segment.rsc.prerender-config.json +28 -0
  616. package/.vercel/output/functions/tasks.segments/tasks.segment.rsc.prerender-fallback.rsc +5 -0
  617. package/.vercel/output/static/404.html +12 -0
  618. package/.vercel/output/static/404.rsc.json +1 -0
  619. package/.vercel/output/static/404.segments/_tree.segment.rsc.json +1 -0
  620. package/.vercel/output/static/500.html +1 -0
  621. package/.vercel/output/static/500.rsc.json +1 -0
  622. package/.vercel/output/static/500.segments/_tree.segment.rsc.json +1 -0
  623. package/.vercel/output/static/_next/__private/trace +2 -0
  624. package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_buildManifest.js +11 -0
  625. package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_clientMiddlewareManifest.js +42 -0
  626. package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_ssgManifest.js +1 -0
  627. package/.vercel/output/static/_next/static/chunks/00~h525bo.q7f.js +1 -0
  628. package/.vercel/output/static/_next/static/chunks/01xlw8hd842-c.js +1 -0
  629. package/.vercel/output/static/_next/static/chunks/0257pdz1-imal.js +2 -0
  630. package/.vercel/output/static/_next/static/chunks/03~yq9q893hmn.js +1 -0
  631. package/.vercel/output/static/_next/static/chunks/04uju~n5s9g7..css +1 -0
  632. package/.vercel/output/static/_next/static/chunks/066jf0nk75nic.css +2 -0
  633. package/.vercel/output/static/_next/static/chunks/085gdrlppedvd.js +1 -0
  634. package/.vercel/output/static/_next/static/chunks/0a5rikwbpt8_7.js +4 -0
  635. package/.vercel/output/static/_next/static/chunks/0b9r.-87w.lvh.js +1 -0
  636. package/.vercel/output/static/_next/static/chunks/0ced2tacwy8v7.js +1 -0
  637. package/.vercel/output/static/_next/static/chunks/0e-.zgw81gela.js +31 -0
  638. package/.vercel/output/static/_next/static/chunks/0gu130fpple04.js +1 -0
  639. package/.vercel/output/static/_next/static/chunks/0jmypv56.iwft.js +1 -0
  640. package/.vercel/output/static/_next/static/chunks/0krr-nvdwqdj1.js +1 -0
  641. package/.vercel/output/static/_next/static/chunks/0mqs00d_9jvzx.js +1 -0
  642. package/.vercel/output/static/_next/static/chunks/0ore4vqiwv2nx.js +1 -0
  643. package/.vercel/output/static/_next/static/chunks/0pqt~8bl3ukh4.js +4 -0
  644. package/.vercel/output/static/_next/static/chunks/0q.t7da_-e4yl.js +4 -0
  645. package/.vercel/output/static/_next/static/chunks/0q3rj30g1oodv.js +7 -0
  646. package/.vercel/output/static/_next/static/chunks/0qp3_l.t4nzzq.js +1 -0
  647. package/.vercel/output/static/_next/static/chunks/0qy1ci2dqfaqg.js +1 -0
  648. package/.vercel/output/static/_next/static/chunks/0u359llqm1_01.js +1 -0
  649. package/.vercel/output/static/_next/static/chunks/0u7ftv8celiqa.js +1 -0
  650. package/.vercel/output/static/_next/static/chunks/0~ijg-d65glam.js +1 -0
  651. package/.vercel/output/static/_next/static/chunks/14bsg3_-taiw4.js +1 -0
  652. package/.vercel/output/static/_next/static/chunks/168q2d2bi7swr.js +7 -0
  653. package/.vercel/output/static/_next/static/chunks/16aqsgrwba4zk.js +1 -0
  654. package/.vercel/output/static/_next/static/chunks/16tw8s4cce9_x.js +1 -0
  655. package/.vercel/output/static/_next/static/chunks/turbopack-01f1xs~cq_~si.js +1 -0
  656. package/.vercel/output/static/_next/static/media/4fa387ec64143e14-s.0wkzw~je483f-.woff2 +0 -0
  657. package/.vercel/output/static/_next/static/media/53b9e256198e5412-s.0-wfv7uh4i7h9.woff2 +0 -0
  658. package/.vercel/output/static/_next/static/media/5ce348bf30bf5439-s.0zgw-jeven.3w.woff2 +0 -0
  659. package/.vercel/output/static/_next/static/media/6306c77e7c8268e4-s.0rhz0arwfsn~5.woff2 +0 -0
  660. package/.vercel/output/static/_next/static/media/7178b3e590c64307-s.0nx0ww8fni_q3.woff2 +0 -0
  661. package/.vercel/output/static/_next/static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2 +0 -0
  662. package/.vercel/output/static/_next/static/media/7d817b4c03b0c5f1-s.0l76wvqk9d84w.woff2 +0 -0
  663. package/.vercel/output/static/_next/static/media/8a480f0b521d4e75-s.0jzbimsg8vl84.woff2 +0 -0
  664. package/.vercel/output/static/_next/static/media/bbc41e54d2fcbd21-s.0k4k9394f2q-k.woff2 +0 -0
  665. package/.vercel/output/static/_next/static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2 +0 -0
  666. package/.vercel/output/static/_next/static/media/favicon.0x3dzn~oxb6tn.ico +0 -0
  667. package/.vercel/output/static/_next/static/media/fef07dbb0973bf53-s.12tyk43_3sh9u.woff2 +0 -0
  668. package/.vercel/output/static/_next/static/not-found.txt +1 -0
  669. package/.vercel/project.json +16 -0
  670. package/AGENTS.md +9 -0
  671. package/CLAUDE.md +1 -0
  672. package/README.md +1 -0
  673. package/app/api/anet/host-supervisors/route.ts +63 -2
  674. package/app/api/anet/node-config/route.ts +145 -168
  675. package/app/api/hub/people/route.ts +48 -0
  676. package/app/api/hub/requirements/[id]/checklist/[itemId]/route.ts +54 -0
  677. package/app/api/hub/requirements/[id]/comments/route.ts +51 -0
  678. package/app/api/hub/requirements/[id]/route.ts +89 -0
  679. package/app/api/hub/requirements/events/route.ts +45 -0
  680. package/app/api/hub/requirements/route.ts +53 -0
  681. package/app/components/CreateNodeWizard.tsx +7 -2
  682. package/app/components/HostSupervisorPicker.tsx +76 -29
  683. package/app/components/NodeSettingsPanel.tsx +28 -25
  684. package/app/components/Sidebar.tsx +4 -0
  685. package/app/components/TaskChatPanel.tsx +6 -6
  686. package/app/components/TaskDetail.tsx +8 -7
  687. package/app/components/TaskList.tsx +6 -7
  688. package/app/components/TopoGraph.tsx +3 -2
  689. package/app/lib/time.ts +23 -0
  690. package/app/org/page.tsx +222 -0
  691. package/app/requirements/[id]/page.tsx +361 -0
  692. package/app/requirements/page.tsx +279 -0
  693. package/app/scheduled-tasks/page.tsx +98 -13
  694. package/apps/desktop/icon.png +0 -0
  695. package/bun.lock +1688 -0
  696. package/electron-builder.json +5 -1
  697. package/package.json +4 -2
  698. package/proxy.ts +1 -0
  699. package/.next/server/chunks/ssr/[root-of-the-server]__0dwa10z._.js +0 -11
  700. package/.next/server/chunks/ssr/[root-of-the-server]__0dwa10z._.js.map +0 -1
  701. package/.next/server/chunks/ssr/[root-of-the-server]__202xetf._.js +0 -11
  702. package/.next/server/chunks/ssr/[root-of-the-server]__202xetf._.js.map +0 -1
  703. package/.next/static/chunks/0pton-t_-fqyu.css +0 -1
  704. package/.next/static/chunks/0z8vfpga444t1.js +0 -1
  705. package/.next/static/chunks/14c8u_tcund0g.js +0 -0
  706. package/.next/static/chunks/2kp8-5cyc-jbg.js +0 -1
  707. package/.next/static/chunks/3a53_ky07bdhz.js +0 -9
  708. package/.next/static/chunks/3im40-b21df3u.js +0 -2
  709. package/.next/static/chunks/3tnbxlq42_jjv.js +0 -1
  710. /package/.next/server/chunks/ssr/{app_0_s8u96._.js.map → app_07bzc6w._.js.map} +0 -0
  711. /package/.next/server/chunks/ssr/{app_0o4bxq0._.js.map → app_0g7oz9w._.js.map} +0 -0
  712. /package/.next/server/chunks/ssr/{app_0x7s72b._.js.map → app_0tt2ueo._.js.map} +0 -0
  713. /package/.next/server/chunks/ssr/{app_081zy6c._.js.map → app_0ugqkd7._.js.map} +0 -0
  714. /package/.next/server/chunks/ssr/{app_1oxcq68._.js.map → app_1e91uc-._.js.map} +0 -0
  715. /package/.next/server/chunks/ssr/{app_1psh956._.js.map → app_1f96aq_._.js.map} +0 -0
  716. /package/.next/server/chunks/ssr/{app_0_dhiwi._.js.map → app_1ua57bx._.js.map} +0 -0
  717. /package/.next/static/{trj9RsCWuEDMfq9BuoKfl → _HZB6K84VKNaxf1K7dqqj}/_buildManifest.js +0 -0
  718. /package/.next/static/{trj9RsCWuEDMfq9BuoKfl → _HZB6K84VKNaxf1K7dqqj}/_ssgManifest.js +0 -0
@@ -1,37 +1,20 @@
1
1
  import { requireDashboardAuth } from '@/app/lib/dashboard-auth';
2
2
  import { hubFetch } from '@/app/lib/hub';
3
+ import { callMcp, parseMcpEnvelope, resolveDefaultNetworkId } from '@/app/lib/hub-mcp';
3
4
 
4
5
  /**
5
- * Per-node config read/write proxy (#260 / #262 — make node settings actually
6
- * take effect). Thin proxy to the hub, using the browser session's V3 user
7
- * token (hubFetch forwards `Authorization: Bearer utok_…`). Endpoint contract =
8
- * RFC-024 (通信工程马, #287/#294/#290, e2e verified):
6
+ * Per-node config proxy for #1316:
7
+ * GET ?node_id=... -> hub REST config snapshot (node-side applied fact)
8
+ * POST -> update_node_config MCP doorbell
9
9
  *
10
- * GET ?node_id=…|alias=… → REST GET /api/nodes/{id}/config — masked snapshot
11
- * { ok, node_id, alias, network_id, config_revision, model, flags{6},
12
- * config_update_capable }. Network scope auto-filtered hub-side.
13
- * POST { node_id|alias, base_revision, model?, flags? }
14
- * → MCP tools/call `update_node_config` at /mcp.
15
- * → { ok, update_id, apply_mode } or { ok:false, error, … }.
16
- *
17
- * apply-status has NO endpoint: the client polls GET and compares the returned
18
- * `config_revision` against the `base_revision` it sent — a bump (> base) means
19
- * applied (snapshot is ground truth; hub atomically finalizes the row + bumps
20
- * nodes.config_revision). See NodeSettingsPanel.
21
- *
22
- * If the hub is unreachable the GET mock-falls back with `mock:true` (panel then
23
- * shows the "后端未接入" note); in normal live operation no mock flag is set.
10
+ * get_config_update and ack_config_update are node-side MCP tools: the node
11
+ * calls them after the dashboard doorbell. The dashboard verifies success by
12
+ * polling the snapshot until config_revision advances. There is no mock success
13
+ * fallback.
24
14
  */
25
15
 
26
- const HUB_GET_PATH = (nodeId: string) => `/api/nodes/${encodeURIComponent(nodeId)}/config`;
27
- const HUB_MCP_PATH = '/mcp'; // MCP Streamable HTTP endpoint (tools/call)
28
16
  const MCP_TOOL_UPDATE = 'update_node_config';
29
- const MCP_PROTOCOL_VERSION = '2025-03-26';
30
17
 
31
- // Editable flags whitelist (RFC-024 — confirmed with 工程马). Anything outside
32
- // this set is dropped before forwarding so the UI can't smuggle unexpected keys
33
- // into the patch. (`teammateMode` is NOT in the hub allowlist — update would
34
- // return invalid_patch — so it's excluded here and from the form.)
35
18
  const EDITABLE_FLAGS = [
36
19
  'permissionMode',
37
20
  'dangerouslySkipPermissions',
@@ -40,99 +23,96 @@ const EDITABLE_FLAGS = [
40
23
  'timeout',
41
24
  ] as const;
42
25
 
43
- // #260 channel edit — the panel toggles enable/disable for these keys only.
44
- // Per-channel secrets (bot token / app secret / allowFrom) stay in the node's
45
- // local config.json, never on the wire from the UI. WeChat is roadmap-only in
46
- // the panel and intentionally not listed here.
47
26
  const EDITABLE_CHANNELS = ['telegram', 'feishu', 'commhub'] as const;
48
27
 
49
- function isJson(res: Response): boolean {
50
- return (res.headers.get('content-type') || '').includes('application/json');
28
+ type ConfigBody = {
29
+ node_id?: string;
30
+ alias?: string;
31
+ base_revision?: number;
32
+ network_id?: string;
33
+ model?: unknown;
34
+ flags?: Record<string, unknown>;
35
+ channels?: unknown;
36
+ };
37
+
38
+ function errText(e: unknown): string {
39
+ return e instanceof Error ? e.message : String(e);
51
40
  }
52
41
 
53
- /**
54
- * Parse an MCP Streamable-HTTP response (either application/json or an SSE
55
- * text/event-stream frame) into the JSON-RPC envelope object.
56
- */
57
- async function parseMcpEnvelope(res: Response): Promise<Record<string, unknown> | null> {
58
- const text = await res.text();
59
- const ct = res.headers.get('content-type') || '';
60
- if (ct.includes('text/event-stream')) {
61
- for (const line of text.split(/\r?\n/)) {
62
- if (!line.startsWith('data:')) continue;
63
- const payload = line.slice(5).trim();
64
- if (!payload) continue;
65
- try {
66
- const o = JSON.parse(payload);
67
- if (o && (o.jsonrpc || o.result || o.error)) return o;
68
- } catch { /* keep scanning frames */ }
69
- }
70
- return null;
71
- }
72
- try {
73
- return JSON.parse(text);
74
- } catch {
75
- return null;
76
- }
42
+ function normalizeResult(result: unknown): Record<string, unknown> {
43
+ return result && typeof result === 'object' ? result as Record<string, unknown> : {};
77
44
  }
78
45
 
79
- export async function GET(req: Request) {
80
- const authFailure = await requireDashboardAuth();
81
- if (authFailure) return authFailure;
82
-
83
- const { searchParams } = new URL(req.url);
84
- // hub only resolves node_id — an alias would silently 404, so don't accept it.
85
- const nodeId = searchParams.get('node_id') || '';
86
- if (!nodeId) return Response.json({ error: 'node_id required' }, { status: 400 });
87
-
88
- try {
89
- const res = await hubFetch(HUB_GET_PATH(nodeId));
90
- if (res.ok && isJson(res)) return Response.json(await res.json());
91
- // Pass a real hub error (e.g. 404 node_not_found) straight through.
92
- if (isJson(res)) return Response.json(await res.json(), { status: res.status });
93
- // Hub unreachable / non-JSON → flagged fallback so the panel still renders.
94
- // (channels kept in the shape for the #31 channel toggles.)
95
- return Response.json({ ok: true, mock: true, node_id: nodeId, model: null, flags: {}, channels: [] });
96
- } catch (e: unknown) {
97
- return Response.json({
98
- ok: true,
99
- mock: true,
100
- node_id: nodeId,
101
- model: null,
102
- flags: {},
103
- channels: [],
104
- _hubError: e instanceof Error ? e.message : String(e),
105
- });
46
+ function numberField(obj: Record<string, unknown>, key: string): number | undefined {
47
+ const value = obj[key];
48
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
49
+ if (typeof value === 'string' && value.trim() !== '') {
50
+ const n = Number(value);
51
+ if (Number.isFinite(n)) return n;
106
52
  }
53
+ return undefined;
107
54
  }
108
55
 
109
- export async function POST(req: Request) {
110
- const authFailure = await requireDashboardAuth();
111
- if (authFailure) return authFailure;
112
-
113
- let body: {
114
- node_id?: string;
115
- base_revision?: number;
116
- network_id?: string;
117
- model?: unknown;
118
- flags?: Record<string, unknown>;
119
- channels?: unknown;
56
+ function exposeConfigSnapshot(result: Record<string, unknown>) {
57
+ const config = normalizeResult(result.config);
58
+ return {
59
+ ...result,
60
+ ...(result.model === undefined && config.model !== undefined ? { model: config.model } : {}),
61
+ ...(result.flags === undefined && config.flags !== undefined ? { flags: config.flags } : {}),
62
+ ...(result.channels === undefined && config.channels !== undefined ? { channels: config.channels } : {}),
63
+ ...(result.config_revision === undefined && config.config_revision !== undefined ? { config_revision: config.config_revision } : {}),
64
+ ...(result.config_update_capable === undefined && config.config_update_capable !== undefined ? { config_update_capable: config.config_update_capable } : {}),
120
65
  };
121
- try {
122
- body = await req.json();
123
- } catch {
124
- return Response.json({ error: 'invalid JSON body' }, { status: 400 });
66
+ }
67
+
68
+ async function callConfigTool(tool: string, args: Record<string, unknown>) {
69
+ const res = await callMcp(tool, args);
70
+ if (res.status === 404 || res.status === 501) {
71
+ return {
72
+ response: Response.json(
73
+ { ok: false, unconfirmed: true, error: `hub tool '${tool}' not available (${res.status})` },
74
+ { status: 501 },
75
+ ),
76
+ };
77
+ }
78
+ if (!res.ok) {
79
+ return { response: Response.json({ ok: false, error: `hub ${res.status}`, status: res.status }, { status: 502 }) };
125
80
  }
81
+ const result = normalizeResult(await parseMcpEnvelope(res));
82
+ if (result.ok === false) {
83
+ return { response: Response.json({ ...result, ok: false, error: String(result.error || `${tool}_failed`) }, { status: 502 }) };
84
+ }
85
+ return { result };
86
+ }
126
87
 
127
- // hub only resolves node_id (no alias fallback — it would silently 404).
128
- const nodeId = body.node_id;
129
- if (!nodeId) return Response.json({ error: 'node_id required' }, { status: 400 });
130
- if (typeof body.base_revision !== 'number') {
131
- return Response.json({ error: 'base_revision (number) required' }, { status: 400 });
88
+ async function getMaskedConfigSnapshot(nodeId: string, networkId?: string | null) {
89
+ const params = new URLSearchParams();
90
+ if (networkId) params.set('network_id', networkId);
91
+ const res = await hubFetch(`/api/nodes/${encodeURIComponent(nodeId)}/config${params.toString() ? `?${params}` : ''}`, {
92
+ headers: { Accept: 'application/json' },
93
+ });
94
+ const contentType = res.headers.get('content-type') || '';
95
+ if (!contentType.includes('application/json')) {
96
+ return {
97
+ response: Response.json(
98
+ { ok: false, node_id: nodeId, error: 'node_config_snapshot_unavailable' },
99
+ { status: 502 },
100
+ ),
101
+ };
132
102
  }
103
+ const data = normalizeResult(await res.json().catch(() => ({})));
104
+ if (data.ok !== true) {
105
+ return {
106
+ response: Response.json(
107
+ { ...data, ok: false, node_id: nodeId, error: String(data.error || 'node_config_snapshot_failed') },
108
+ { status: res.ok ? 502 : res.status },
109
+ ),
110
+ };
111
+ }
112
+ return { result: data };
113
+ }
133
114
 
134
- // Build the partial patch — only the fields the client sends. Flags and
135
- // channels are whitelisted to the editable contract.
115
+ function buildPatch(body: ConfigBody) {
136
116
  const patch: { model?: unknown; flags?: Record<string, unknown>; channels?: string[] } = {};
137
117
  if (body.model !== undefined) patch.model = body.model;
138
118
  if (body.flags && typeof body.flags === 'object') {
@@ -142,10 +122,6 @@ export async function POST(req: Request) {
142
122
  }
143
123
  if (Object.keys(flags).length > 0) patch.flags = flags;
144
124
  }
145
- // Whitelist channels (#31) — accept string[] of EDITABLE_CHANNELS keys only.
146
- // Any other shape or key is dropped, so the panel can never smuggle a secret
147
- // payload or an unknown channel name to the hub. Channels ride INSIDE the
148
- // RFC-024 patch — update_node_config's schema is { model?, flags?, channels? }.
149
125
  if (Array.isArray(body.channels)) {
150
126
  const allow = new Set<string>(EDITABLE_CHANNELS);
151
127
  const seen = new Set<string>();
@@ -159,73 +135,74 @@ export async function POST(req: Request) {
159
135
  }
160
136
  patch.channels = channels;
161
137
  }
162
- if (patch.model === undefined && !patch.flags && !patch.channels) {
163
- return Response.json({ ok: false, error: 'empty_patch' }, { status: 400 });
164
- }
138
+ return patch;
139
+ }
165
140
 
166
- // Resolve network_id — REQUIRED by update_node_config when the token's
167
- // current_network is null (dry-run verified: omitting it → permission_denied).
168
- // Prefer the node's own network (sent by the client, who knows which network
169
- // the node is in) — re-deriving from /api/auth/me networks[0] picks the wrong
170
- // network for multi-network users (regression-test caught a false
171
- // cross_network_node). The hub still authorizes (SEC-1), so trusting the
172
- // client's network_id is safe. Fall back to the me-derivation.
173
- let networkId: string | undefined = body.network_id;
174
- if (!networkId) {
175
- try {
176
- const meRes = await hubFetch('/api/auth/me');
177
- if (meRes.ok) {
178
- const me = await meRes.json();
179
- networkId = me?.current_network || me?.networks?.[0]?.network_id;
180
- }
181
- } catch { /* fall through — hub may still infer if current_network is set */ }
141
+ export async function GET(req: Request) {
142
+ const authFailure = await requireDashboardAuth();
143
+ if (authFailure) return authFailure;
144
+
145
+ const { searchParams } = new URL(req.url);
146
+ const networkId = searchParams.get('network_id') || (await resolveDefaultNetworkId());
147
+ const nodeId = searchParams.get('node_id') || searchParams.get('alias') || '';
148
+ if (!nodeId) return Response.json({ error: 'node_id or alias required' }, { status: 400 });
149
+ try {
150
+ const out = await getMaskedConfigSnapshot(nodeId, networkId);
151
+ if (out.response) return out.response;
152
+ const result = exposeConfigSnapshot(out.result);
153
+ const currentRevision = numberField(result, 'config_revision') ?? 0;
154
+ const baseRevision = numberField(Object.fromEntries(searchParams), 'base_revision');
155
+ if (baseRevision !== undefined) {
156
+ return Response.json({
157
+ ok: true,
158
+ node_id: nodeId,
159
+ ...result,
160
+ status: currentRevision > baseRevision ? 'applied' : 'pending',
161
+ base_revision: baseRevision,
162
+ });
163
+ }
164
+ return Response.json({ ok: true, node_id: nodeId, ...result });
165
+ } catch (e: unknown) {
166
+ return Response.json({ ok: false, node_id: nodeId, error: errText(e) }, { status: 502 });
182
167
  }
168
+ }
183
169
 
184
- const rpcBody = {
185
- jsonrpc: '2.0',
186
- id: 1,
187
- method: 'tools/call',
188
- params: {
189
- name: MCP_TOOL_UPDATE,
190
- arguments: { node_id: nodeId, base_revision: body.base_revision, patch, ...(networkId ? { network_id: networkId } : {}) },
191
- },
192
- };
170
+ export async function POST(req: Request) {
171
+ const authFailure = await requireDashboardAuth();
172
+ if (authFailure) return authFailure;
193
173
 
174
+ let body: ConfigBody;
194
175
  try {
195
- const res = await hubFetch(HUB_MCP_PATH, {
196
- method: 'POST',
197
- headers: {
198
- 'Content-Type': 'application/json',
199
- Accept: 'application/json, text/event-stream',
200
- 'MCP-Protocol-Version': MCP_PROTOCOL_VERSION,
201
- },
202
- body: JSON.stringify(rpcBody),
203
- });
204
-
205
- if (!res.ok && res.status >= 500) {
206
- return Response.json({ ok: false, error: `hub ${res.status}` }, { status: 502 });
207
- }
176
+ body = await req.json();
177
+ } catch {
178
+ return Response.json({ error: 'invalid JSON body' }, { status: 400 });
179
+ }
208
180
 
209
- const rpc = await parseMcpEnvelope(res);
210
- if (!rpc) return Response.json({ ok: false, error: 'mcp_unparseable' }, { status: 502 });
211
- if (rpc.error) {
212
- const err = rpc.error as { message?: string };
213
- return Response.json({ ok: false, error: 'mcp_error', detail: err?.message }, { status: 502 });
214
- }
181
+ const nodeId = body.node_id || body.alias;
182
+ if (!nodeId) return Response.json({ error: 'node_id or alias required' }, { status: 400 });
183
+ if (typeof body.base_revision !== 'number') {
184
+ return Response.json({ error: 'base_revision (number) required' }, { status: 400 });
185
+ }
215
186
 
216
- // tools/call wraps the tool's JSON in result.content[0].text.
217
- const result = rpc.result as { content?: Array<{ text?: string }> } | undefined;
218
- const textContent = result?.content?.[0]?.text;
219
- let inner: Record<string, unknown> = {};
220
- if (typeof textContent === 'string') {
221
- try { inner = JSON.parse(textContent); } catch { inner = {}; }
222
- } else if (rpc.result && typeof rpc.result === 'object') {
223
- inner = rpc.result as Record<string, unknown>;
224
- }
225
- // inner = { ok:true, update_id, apply_mode } | { ok:false, error, … }
226
- // App-level errors come back HTTP 200 (ok:false) so the client maps them.
227
- return Response.json(inner);
187
+ const patch = buildPatch(body);
188
+ if (patch.model === undefined && !patch.flags && !patch.channels) {
189
+ return Response.json({ ok: false, error: 'empty_patch' }, { status: 400 });
190
+ }
191
+
192
+ const networkId = body.network_id || (await resolveDefaultNetworkId());
193
+ const args = {
194
+ node_id: nodeId,
195
+ base_revision: body.base_revision,
196
+ patch,
197
+ ...(networkId ? { network_id: networkId } : {}),
198
+ };
199
+
200
+ try {
201
+ const out = await callConfigTool(MCP_TOOL_UPDATE, args);
202
+ if (out.response) return out.response;
203
+ const result = out.result;
204
+ return Response.json({ ok: true, node_id: nodeId, base_revision: body.base_revision, status: 'pending', ...exposeConfigSnapshot(result) });
228
205
  } catch (e: unknown) {
229
- return Response.json({ ok: false, error: 'hub_unreachable', detail: e instanceof Error ? e.message : String(e) }, { status: 502 });
206
+ return Response.json({ ok: false, node_id: nodeId, error: errText(e) }, { status: 502 });
230
207
  }
231
208
  }
@@ -0,0 +1,48 @@
1
+ import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
2
+
3
+ const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
4
+
5
+ async function hubHeaders(): Promise<Record<string, string>> {
6
+ const userToken = await getV3UserToken();
7
+ const h: Record<string, string> = {};
8
+ if (userToken) h['Authorization'] = `Bearer ${userToken}`;
9
+ return h;
10
+ }
11
+
12
+ /**
13
+ * Org directory — #1635.
14
+ *
15
+ * The Hub already builds this projection for MCP `requirements_people`
16
+ * (people + department + the Agents each person owns). Its REST twin is
17
+ * `/api/requirements/people/directory`; there is no `/api/people`. Proxying
18
+ * the existing one keeps a single source of truth instead of a second query.
19
+ */
20
+ export async function GET(req: Request) {
21
+ const authFailure = await requireDashboardAuth();
22
+ if (authFailure) return authFailure;
23
+
24
+ const { searchParams } = new URL(req.url);
25
+ const params = new URLSearchParams();
26
+ for (const key of ['q', 'limit', 'offset']) {
27
+ const value = searchParams.get(key);
28
+ if (value) params.set(key, value);
29
+ }
30
+ if (!params.has('limit')) params.set('limit', '100');
31
+
32
+ try {
33
+ const res = await fetch(`${HUB_URL}/api/requirements/people/directory?${params.toString()}`, {
34
+ headers: await hubHeaders(),
35
+ next: { revalidate: 0 },
36
+ });
37
+ const contentType = res.headers.get('content-type') || '';
38
+ if (!contentType.includes('application/json')) {
39
+ return Response.json({ ok: false, error: 'hub_not_json', status: res.status }, { status: 502 });
40
+ }
41
+ return Response.json(await res.json(), { status: res.status });
42
+ } catch (e: unknown) {
43
+ return Response.json(
44
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
45
+ { status: 502 },
46
+ );
47
+ }
48
+ }
@@ -0,0 +1,54 @@
1
+ import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
2
+
3
+ const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
4
+
5
+ async function hubHeaders(): Promise<Record<string, string>> {
6
+ const userToken = await getV3UserToken();
7
+ const h: Record<string, string> = {};
8
+ if (userToken) h['Authorization'] = `Bearer ${userToken}`;
9
+ return h;
10
+ }
11
+
12
+ /**
13
+ * Checklist toggle — #1634. Only that one item is written (Hub patches a
14
+ * single entry), so two people editing different items do not clobber
15
+ * each other.
16
+ */
17
+ export async function PATCH(req: Request, ctx: { params: Promise<{ id: string; itemId: string }> }) {
18
+ const authFailure = await requireDashboardAuth();
19
+ if (authFailure) return authFailure;
20
+
21
+ const { id, itemId } = await ctx.params;
22
+ if (!/^req_[A-Za-z0-9_-]+$/.test(id || '') || !/^[A-Za-z0-9_-]{1,40}$/.test(itemId || '')) {
23
+ return Response.json({ ok: false, error: 'invalid_checklist_target' }, { status: 400 });
24
+ }
25
+
26
+ let body: { done?: unknown };
27
+ try {
28
+ body = await req.json();
29
+ } catch {
30
+ return Response.json({ ok: false, error: 'invalid_json' }, { status: 400 });
31
+ }
32
+ if (typeof body.done !== 'boolean') {
33
+ return Response.json({ ok: false, error: 'done_must_be_boolean' }, { status: 400 });
34
+ }
35
+
36
+ try {
37
+ const res = await fetch(
38
+ `${HUB_URL}/api/requirements/${encodeURIComponent(id)}/checklist/${encodeURIComponent(itemId)}`,
39
+ {
40
+ method: 'PATCH',
41
+ headers: { ...(await hubHeaders()), 'Content-Type': 'application/json' },
42
+ body: JSON.stringify({ done: body.done }),
43
+ next: { revalidate: 0 },
44
+ },
45
+ );
46
+ const data = await res.json().catch(() => ({}));
47
+ return Response.json(data, { status: res.status });
48
+ } catch (e: unknown) {
49
+ return Response.json(
50
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
51
+ { status: 502 },
52
+ );
53
+ }
54
+ }
@@ -0,0 +1,51 @@
1
+ import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
2
+
3
+ const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
4
+
5
+ async function hubHeaders(): Promise<Record<string, string>> {
6
+ const userToken = await getV3UserToken();
7
+ const h: Record<string, string> = {};
8
+ if (userToken) h['Authorization'] = `Bearer ${userToken}`;
9
+ return h;
10
+ }
11
+
12
+ /**
13
+ * Comments — #1634. Hub's path is the plural `/comments` (a singular
14
+ * `/comment` route 404s); it requires non-empty `text` and appends to the
15
+ * timeline without touching the description.
16
+ */
17
+ export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
18
+ const authFailure = await requireDashboardAuth();
19
+ if (authFailure) return authFailure;
20
+
21
+ const { id } = await ctx.params;
22
+ if (!/^req_[A-Za-z0-9_-]+$/.test(id || '')) {
23
+ return Response.json({ ok: false, error: 'invalid_requirement_id' }, { status: 400 });
24
+ }
25
+
26
+ let body: { text?: unknown };
27
+ try {
28
+ body = await req.json();
29
+ } catch {
30
+ return Response.json({ ok: false, error: 'invalid_json' }, { status: 400 });
31
+ }
32
+ const text = typeof body.text === 'string' ? body.text.trim() : '';
33
+ if (!text) return Response.json({ ok: false, error: 'invalid_comment', field: 'text' }, { status: 400 });
34
+ if (text.length > 4000) return Response.json({ ok: false, error: 'comment_too_long' }, { status: 400 });
35
+
36
+ try {
37
+ const res = await fetch(`${HUB_URL}/api/requirements/${encodeURIComponent(id)}/comments`, {
38
+ method: 'POST',
39
+ headers: { ...(await hubHeaders()), 'Content-Type': 'application/json' },
40
+ body: JSON.stringify({ text }),
41
+ next: { revalidate: 0 },
42
+ });
43
+ const data = await res.json().catch(() => ({}));
44
+ return Response.json(data, { status: res.status });
45
+ } catch (e: unknown) {
46
+ return Response.json(
47
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
48
+ { status: 502 },
49
+ );
50
+ }
51
+ }
@@ -0,0 +1,89 @@
1
+ import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
2
+
3
+ const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
4
+
5
+ async function hubHeaders(): Promise<Record<string, string>> {
6
+ const userToken = await getV3UserToken();
7
+ const h: Record<string, string> = {};
8
+ if (userToken) h['Authorization'] = `Bearer ${userToken}`;
9
+ return h;
10
+ }
11
+
12
+ /**
13
+ * One requirement — #1633. Hub only resolves `req_…` ids on this path;
14
+ * a short number (#N) 404s, so the page always links by id.
15
+ */
16
+ export async function GET(_req: Request, ctx: { params: Promise<{ id: string }> }) {
17
+ const authFailure = await requireDashboardAuth();
18
+ if (authFailure) return authFailure;
19
+
20
+ const { id } = await ctx.params;
21
+ if (!id || !/^req_[A-Za-z0-9_-]+$/.test(id)) {
22
+ return Response.json({ ok: false, error: 'invalid_requirement_id' }, { status: 400 });
23
+ }
24
+
25
+ try {
26
+ const res = await fetch(`${HUB_URL}/api/requirements/${encodeURIComponent(id)}`, {
27
+ headers: await hubHeaders(),
28
+ next: { revalidate: 0 },
29
+ });
30
+ const contentType = res.headers.get('content-type') || '';
31
+ if (!contentType.includes('application/json')) {
32
+ return Response.json({ ok: false, error: 'hub_not_json', status: res.status }, { status: 502 });
33
+ }
34
+ return Response.json(await res.json(), { status: res.status });
35
+ } catch (e: unknown) {
36
+ return Response.json(
37
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
38
+ { status: 502 },
39
+ );
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Writes — #1634. Hub owns every rule (owner must be human, node tokens may
45
+ * not delete, checklist ids are server-side); this proxy only forwards the
46
+ * whitelisted fields and passes Hub's error code through untouched so the UI
47
+ * can say *why* instead of failing silently.
48
+ */
49
+ const WRITABLE = ['column', 'priority', 'due', 'start', 'tags', 'name'] as const;
50
+
51
+ export async function PATCH(req: Request, ctx: { params: Promise<{ id: string }> }) {
52
+ const authFailure = await requireDashboardAuth();
53
+ if (authFailure) return authFailure;
54
+
55
+ const { id } = await ctx.params;
56
+ if (!id || !/^req_[A-Za-z0-9_-]+$/.test(id)) {
57
+ return Response.json({ ok: false, error: 'invalid_requirement_id' }, { status: 400 });
58
+ }
59
+
60
+ let body: Record<string, unknown>;
61
+ try {
62
+ body = await req.json();
63
+ } catch {
64
+ return Response.json({ ok: false, error: 'invalid_json' }, { status: 400 });
65
+ }
66
+ const patch: Record<string, unknown> = {};
67
+ for (const key of WRITABLE) {
68
+ if (Object.prototype.hasOwnProperty.call(body, key)) patch[key] = body[key];
69
+ }
70
+ if (Object.keys(patch).length === 0) {
71
+ return Response.json({ ok: false, error: 'empty_patch' }, { status: 400 });
72
+ }
73
+
74
+ try {
75
+ const res = await fetch(`${HUB_URL}/api/requirements/${encodeURIComponent(id)}`, {
76
+ method: 'PATCH',
77
+ headers: { ...(await hubHeaders()), 'Content-Type': 'application/json' },
78
+ body: JSON.stringify(patch),
79
+ next: { revalidate: 0 },
80
+ });
81
+ const data = await res.json().catch(() => ({}));
82
+ return Response.json(data, { status: res.status });
83
+ } catch (e: unknown) {
84
+ return Response.json(
85
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
86
+ { status: 502 },
87
+ );
88
+ }
89
+ }
@@ -0,0 +1,45 @@
1
+ import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
2
+
3
+ const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
4
+
5
+ async function hubHeaders(): Promise<Record<string, string>> {
6
+ const userToken = await getV3UserToken();
7
+ const h: Record<string, string> = {};
8
+ if (userToken) h['Authorization'] = `Bearer ${userToken}`;
9
+ return h;
10
+ }
11
+
12
+ /**
13
+ * Requirement activity timeline (动态) — #1633.
14
+ *
15
+ * Hub's shape here is NOT /api/requirements/<id>/events (that 404s).
16
+ * The working endpoint is a query param on the collection route.
17
+ */
18
+ export async function GET(req: Request) {
19
+ const authFailure = await requireDashboardAuth();
20
+ if (authFailure) return authFailure;
21
+
22
+ const { searchParams } = new URL(req.url);
23
+ const requirementId = searchParams.get('requirement_id') || '';
24
+ if (!/^req_[A-Za-z0-9_-]+$/.test(requirementId)) {
25
+ return Response.json({ ok: false, error: 'invalid_requirement_id' }, { status: 400 });
26
+ }
27
+ const limit = searchParams.get('limit') || '100';
28
+
29
+ try {
30
+ const res = await fetch(
31
+ `${HUB_URL}/api/requirements/events?requirement_id=${encodeURIComponent(requirementId)}&limit=${encodeURIComponent(limit)}`,
32
+ { headers: await hubHeaders(), next: { revalidate: 0 } },
33
+ );
34
+ const contentType = res.headers.get('content-type') || '';
35
+ if (!contentType.includes('application/json')) {
36
+ return Response.json({ ok: false, error: 'hub_not_json', status: res.status }, { status: 502 });
37
+ }
38
+ return Response.json(await res.json(), { status: res.status });
39
+ } catch (e: unknown) {
40
+ return Response.json(
41
+ { ok: false, error: 'CommHub unreachable', detail: e instanceof Error ? e.message : String(e) },
42
+ { status: 502 },
43
+ );
44
+ }
45
+ }