@a5c-ai/babysitter-observer-dashboard 5.0.1-staging.7a8768ec

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 (513) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-path-routes-manifest.json +16 -0
  3. package/.next/build-manifest.json +23 -0
  4. package/.next/export-marker.json +6 -0
  5. package/.next/fallback-build-manifest.json +13 -0
  6. package/.next/images-manifest.json +68 -0
  7. package/.next/next-minimal-server.js.nft.json +1 -0
  8. package/.next/next-server.js.nft.json +1 -0
  9. package/.next/package.json +1 -0
  10. package/.next/prerender-manifest.json +114 -0
  11. package/.next/required-server-files.json +334 -0
  12. package/.next/routes-manifest.json +139 -0
  13. package/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
  14. package/.next/server/app/_global-error/page/build-manifest.json +19 -0
  15. package/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
  16. package/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
  17. package/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
  18. package/.next/server/app/_global-error/page.js +9 -0
  19. package/.next/server/app/_global-error/page.js.map +5 -0
  20. package/.next/server/app/_global-error/page.js.nft.json +1 -0
  21. package/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
  22. package/.next/server/app/_global-error.html +1 -0
  23. package/.next/server/app/_global-error.meta +15 -0
  24. package/.next/server/app/_global-error.rsc +14 -0
  25. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
  26. package/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
  27. package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  28. package/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
  29. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  30. package/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
  31. package/.next/server/app/_not-found/page/build-manifest.json +19 -0
  32. package/.next/server/app/_not-found/page/next-font-manifest.json +6 -0
  33. package/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
  34. package/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
  35. package/.next/server/app/_not-found/page.js +13 -0
  36. package/.next/server/app/_not-found/page.js.map +5 -0
  37. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  38. package/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
  39. package/.next/server/app/_not-found.html +1 -0
  40. package/.next/server/app/_not-found.meta +16 -0
  41. package/.next/server/app/_not-found.rsc +19 -0
  42. package/.next/server/app/_not-found.segments/_full.segment.rsc +19 -0
  43. package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
  44. package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -0
  45. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +6 -0
  46. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
  47. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
  48. package/.next/server/app/api/config/route/app-paths-manifest.json +3 -0
  49. package/.next/server/app/api/config/route/build-manifest.json +9 -0
  50. package/.next/server/app/api/config/route/server-reference-manifest.json +4 -0
  51. package/.next/server/app/api/config/route.js +8 -0
  52. package/.next/server/app/api/config/route.js.map +5 -0
  53. package/.next/server/app/api/config/route.js.nft.json +1 -0
  54. package/.next/server/app/api/config/route_client-reference-manifest.js +3 -0
  55. package/.next/server/app/api/digest/route/app-paths-manifest.json +3 -0
  56. package/.next/server/app/api/digest/route/build-manifest.json +9 -0
  57. package/.next/server/app/api/digest/route/server-reference-manifest.json +4 -0
  58. package/.next/server/app/api/digest/route.js +9 -0
  59. package/.next/server/app/api/digest/route.js.map +5 -0
  60. package/.next/server/app/api/digest/route.js.nft.json +1 -0
  61. package/.next/server/app/api/digest/route_client-reference-manifest.js +3 -0
  62. package/.next/server/app/api/runs/[runId]/events/route/app-paths-manifest.json +3 -0
  63. package/.next/server/app/api/runs/[runId]/events/route/build-manifest.json +9 -0
  64. package/.next/server/app/api/runs/[runId]/events/route/server-reference-manifest.json +4 -0
  65. package/.next/server/app/api/runs/[runId]/events/route.js +8 -0
  66. package/.next/server/app/api/runs/[runId]/events/route.js.map +5 -0
  67. package/.next/server/app/api/runs/[runId]/events/route.js.nft.json +1 -0
  68. package/.next/server/app/api/runs/[runId]/events/route_client-reference-manifest.js +3 -0
  69. package/.next/server/app/api/runs/[runId]/route/app-paths-manifest.json +3 -0
  70. package/.next/server/app/api/runs/[runId]/route/build-manifest.json +9 -0
  71. package/.next/server/app/api/runs/[runId]/route/server-reference-manifest.json +4 -0
  72. package/.next/server/app/api/runs/[runId]/route.js +9 -0
  73. package/.next/server/app/api/runs/[runId]/route.js.map +5 -0
  74. package/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -0
  75. package/.next/server/app/api/runs/[runId]/route_client-reference-manifest.js +3 -0
  76. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/app-paths-manifest.json +3 -0
  77. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/build-manifest.json +9 -0
  78. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/server-reference-manifest.json +4 -0
  79. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js +8 -0
  80. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js.map +5 -0
  81. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js.nft.json +1 -0
  82. package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route_client-reference-manifest.js +3 -0
  83. package/.next/server/app/api/runs/route/app-paths-manifest.json +3 -0
  84. package/.next/server/app/api/runs/route/build-manifest.json +9 -0
  85. package/.next/server/app/api/runs/route/server-reference-manifest.json +4 -0
  86. package/.next/server/app/api/runs/route.js +9 -0
  87. package/.next/server/app/api/runs/route.js.map +5 -0
  88. package/.next/server/app/api/runs/route.js.nft.json +1 -0
  89. package/.next/server/app/api/runs/route_client-reference-manifest.js +3 -0
  90. package/.next/server/app/api/stream/route/app-paths-manifest.json +3 -0
  91. package/.next/server/app/api/stream/route/build-manifest.json +9 -0
  92. package/.next/server/app/api/stream/route/server-reference-manifest.json +4 -0
  93. package/.next/server/app/api/stream/route.js +8 -0
  94. package/.next/server/app/api/stream/route.js.map +5 -0
  95. package/.next/server/app/api/stream/route.js.nft.json +1 -0
  96. package/.next/server/app/api/stream/route_client-reference-manifest.js +3 -0
  97. package/.next/server/app/api/test/route/app-paths-manifest.json +3 -0
  98. package/.next/server/app/api/test/route/build-manifest.json +9 -0
  99. package/.next/server/app/api/test/route/server-reference-manifest.json +4 -0
  100. package/.next/server/app/api/test/route.js +6 -0
  101. package/.next/server/app/api/test/route.js.map +5 -0
  102. package/.next/server/app/api/test/route.js.nft.json +1 -0
  103. package/.next/server/app/api/test/route_client-reference-manifest.js +3 -0
  104. package/.next/server/app/api/version/route/app-paths-manifest.json +3 -0
  105. package/.next/server/app/api/version/route/build-manifest.json +9 -0
  106. package/.next/server/app/api/version/route/server-reference-manifest.json +4 -0
  107. package/.next/server/app/api/version/route.js +7 -0
  108. package/.next/server/app/api/version/route.js.map +5 -0
  109. package/.next/server/app/api/version/route.js.nft.json +1 -0
  110. package/.next/server/app/api/version/route_client-reference-manifest.js +3 -0
  111. package/.next/server/app/icon.svg/route/app-paths-manifest.json +3 -0
  112. package/.next/server/app/icon.svg/route/build-manifest.json +9 -0
  113. package/.next/server/app/icon.svg/route.js +7 -0
  114. package/.next/server/app/icon.svg/route.js.map +5 -0
  115. package/.next/server/app/icon.svg/route.js.nft.json +1 -0
  116. package/.next/server/app/icon.svg.body +20 -0
  117. package/.next/server/app/icon.svg.meta +1 -0
  118. package/.next/server/app/index.html +1 -0
  119. package/.next/server/app/index.meta +14 -0
  120. package/.next/server/app/index.rsc +21 -0
  121. package/.next/server/app/index.segments/__PAGE__.segment.rsc +9 -0
  122. package/.next/server/app/index.segments/_full.segment.rsc +21 -0
  123. package/.next/server/app/index.segments/_head.segment.rsc +6 -0
  124. package/.next/server/app/index.segments/_index.segment.rsc +8 -0
  125. package/.next/server/app/index.segments/_tree.segment.rsc +2 -0
  126. package/.next/server/app/page/app-paths-manifest.json +3 -0
  127. package/.next/server/app/page/build-manifest.json +19 -0
  128. package/.next/server/app/page/next-font-manifest.json +6 -0
  129. package/.next/server/app/page/react-loadable-manifest.json +1 -0
  130. package/.next/server/app/page/server-reference-manifest.json +17 -0
  131. package/.next/server/app/page.js +15 -0
  132. package/.next/server/app/page.js.map +5 -0
  133. package/.next/server/app/page.js.nft.json +1 -0
  134. package/.next/server/app/page_client-reference-manifest.js +3 -0
  135. package/.next/server/app/runs/[runId]/page/app-paths-manifest.json +3 -0
  136. package/.next/server/app/runs/[runId]/page/build-manifest.json +19 -0
  137. package/.next/server/app/runs/[runId]/page/next-font-manifest.json +6 -0
  138. package/.next/server/app/runs/[runId]/page/react-loadable-manifest.json +22 -0
  139. package/.next/server/app/runs/[runId]/page/server-reference-manifest.json +17 -0
  140. package/.next/server/app/runs/[runId]/page.js +15 -0
  141. package/.next/server/app/runs/[runId]/page.js.map +5 -0
  142. package/.next/server/app/runs/[runId]/page.js.nft.json +1 -0
  143. package/.next/server/app/runs/[runId]/page_client-reference-manifest.js +3 -0
  144. package/.next/server/app-paths-manifest.json +16 -0
  145. package/.next/server/chunks/01oi_server_app_api_runs_[runId]_tasks_[effectId]_route_actions_0r72yai.js +3 -0
  146. package/.next/server/chunks/01oi_server_app_api_runs_[runId]_tasks_[effectId]_route_actions_0r72yai.js.map +1 -0
  147. package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_events_route_actions_0~msldk.js +3 -0
  148. package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_events_route_actions_0~msldk.js.map +1 -0
  149. package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_route_actions_09iz0n6.js +3 -0
  150. package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_route_actions_09iz0n6.js.map +1 -0
  151. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_config_route_actions_0~eypoa.js +3 -0
  152. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_config_route_actions_0~eypoa.js.map +1 -0
  153. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_digest_route_actions_04jj5zs.js +3 -0
  154. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_digest_route_actions_04jj5zs.js.map +1 -0
  155. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_runs_route_actions_0~-t-o4.js +3 -0
  156. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_runs_route_actions_0~-t-o4.js.map +1 -0
  157. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_stream_route_actions_0fkmv2_.js +3 -0
  158. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_stream_route_actions_0fkmv2_.js.map +1 -0
  159. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_test_route_actions_00ugava.js +3 -0
  160. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_test_route_actions_00ugava.js.map +1 -0
  161. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_version_route_actions_0~v3ojm.js +3 -0
  162. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_version_route_actions_0~v3ojm.js.map +1 -0
  163. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_icon_svg_route_actions_0yypxkm.js +3 -0
  164. package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_icon_svg_route_actions_0yypxkm.js.map +1 -0
  165. package/.next/server/chunks/[root-of-the-server]__0.6bt.6._.js +3 -0
  166. package/.next/server/chunks/[root-of-the-server]__0.6bt.6._.js.map +1 -0
  167. package/.next/server/chunks/[root-of-the-server]__08kwev1._.js +3 -0
  168. package/.next/server/chunks/[root-of-the-server]__08kwev1._.js.map +1 -0
  169. package/.next/server/chunks/[root-of-the-server]__096el.d._.js +3 -0
  170. package/.next/server/chunks/[root-of-the-server]__096el.d._.js.map +1 -0
  171. package/.next/server/chunks/[root-of-the-server]__0_bmt4z._.js +3 -0
  172. package/.next/server/chunks/[root-of-the-server]__0_bmt4z._.js.map +1 -0
  173. package/.next/server/chunks/[root-of-the-server]__0_ln2d2._.js +3 -0
  174. package/.next/server/chunks/[root-of-the-server]__0_ln2d2._.js.map +1 -0
  175. package/.next/server/chunks/[root-of-the-server]__0al3v65._.js +3 -0
  176. package/.next/server/chunks/[root-of-the-server]__0al3v65._.js.map +1 -0
  177. package/.next/server/chunks/[root-of-the-server]__0gf516b._.js +3 -0
  178. package/.next/server/chunks/[root-of-the-server]__0gf516b._.js.map +1 -0
  179. package/.next/server/chunks/[root-of-the-server]__0kdfw4x._.js +3 -0
  180. package/.next/server/chunks/[root-of-the-server]__0kdfw4x._.js.map +1 -0
  181. package/.next/server/chunks/[root-of-the-server]__0pxt00h._.js +3 -0
  182. package/.next/server/chunks/[root-of-the-server]__0pxt00h._.js.map +1 -0
  183. package/.next/server/chunks/[root-of-the-server]__0rubnza._.js +3 -0
  184. package/.next/server/chunks/[root-of-the-server]__0rubnza._.js.map +1 -0
  185. package/.next/server/chunks/[root-of-the-server]__0tn9iud._.js +3 -0
  186. package/.next/server/chunks/[root-of-the-server]__0tn9iud._.js.map +1 -0
  187. package/.next/server/chunks/[root-of-the-server]__0ws5o6i._.js +3 -0
  188. package/.next/server/chunks/[root-of-the-server]__0ws5o6i._.js.map +1 -0
  189. package/.next/server/chunks/[turbopack]_runtime.js +903 -0
  190. package/.next/server/chunks/[turbopack]_runtime.js.map +11 -0
  191. package/.next/server/chunks/node_modules_next_04~_e52._.js +13 -0
  192. package/.next/server/chunks/node_modules_next_04~_e52._.js.map +1 -0
  193. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js +9 -0
  194. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js.map +1 -0
  195. package/.next/server/chunks/packages_observer-dashboard_src_lib_02.vvb.._.js +3 -0
  196. package/.next/server/chunks/packages_observer-dashboard_src_lib_02.vvb.._.js.map +1 -0
  197. package/.next/server/chunks/packages_observer-dashboard_src_lib_0rqgpk0._.js +3 -0
  198. package/.next/server/chunks/packages_observer-dashboard_src_lib_0rqgpk0._.js.map +1 -0
  199. package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__global-error_page_actions_0ekoxmy.js +3 -0
  200. package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__global-error_page_actions_0ekoxmy.js.map +1 -0
  201. package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__not-found_page_actions_09b3ti3.js +3 -0
  202. package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__not-found_page_actions_09b3ti3.js.map +1 -0
  203. package/.next/server/chunks/ssr/[root-of-the-server]__006f7~t._.js +4 -0
  204. package/.next/server/chunks/ssr/[root-of-the-server]__006f7~t._.js.map +1 -0
  205. package/.next/server/chunks/ssr/[root-of-the-server]__02jgvbi._.js +3 -0
  206. package/.next/server/chunks/ssr/[root-of-the-server]__02jgvbi._.js.map +1 -0
  207. package/.next/server/chunks/ssr/[root-of-the-server]__04j8t~1._.js +3 -0
  208. package/.next/server/chunks/ssr/[root-of-the-server]__04j8t~1._.js.map +1 -0
  209. package/.next/server/chunks/ssr/[root-of-the-server]__09c~s.0._.js +33 -0
  210. package/.next/server/chunks/ssr/[root-of-the-server]__09c~s.0._.js.map +1 -0
  211. package/.next/server/chunks/ssr/[root-of-the-server]__0cpy61n._.js +3 -0
  212. package/.next/server/chunks/ssr/[root-of-the-server]__0cpy61n._.js.map +1 -0
  213. package/.next/server/chunks/ssr/[root-of-the-server]__0cwa32j._.js +3 -0
  214. package/.next/server/chunks/ssr/[root-of-the-server]__0cwa32j._.js.map +1 -0
  215. package/.next/server/chunks/ssr/[root-of-the-server]__0fk_g0j._.js +19 -0
  216. package/.next/server/chunks/ssr/[root-of-the-server]__0fk_g0j._.js.map +1 -0
  217. package/.next/server/chunks/ssr/[root-of-the-server]__0pddpic._.js +3 -0
  218. package/.next/server/chunks/ssr/[root-of-the-server]__0pddpic._.js.map +1 -0
  219. package/.next/server/chunks/ssr/[root-of-the-server]__0pvtneq._.js +3 -0
  220. package/.next/server/chunks/ssr/[root-of-the-server]__0pvtneq._.js.map +1 -0
  221. package/.next/server/chunks/ssr/[root-of-the-server]__0xc-2vm._.js +3 -0
  222. package/.next/server/chunks/ssr/[root-of-the-server]__0xc-2vm._.js.map +1 -0
  223. package/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js +33 -0
  224. package/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js.map +1 -0
  225. package/.next/server/chunks/ssr/[turbopack]_runtime.js +903 -0
  226. package/.next/server/chunks/ssr/[turbopack]_runtime.js.map +11 -0
  227. package/.next/server/chunks/ssr/_00yo1im._.js +3 -0
  228. package/.next/server/chunks/ssr/_00yo1im._.js.map +1 -0
  229. package/.next/server/chunks/ssr/_03sbc.o._.js +3 -0
  230. package/.next/server/chunks/ssr/_03sbc.o._.js.map +1 -0
  231. package/.next/server/chunks/ssr/_04z5ea0._.js +3 -0
  232. package/.next/server/chunks/ssr/_04z5ea0._.js.map +1 -0
  233. package/.next/server/chunks/ssr/_0gmb3g_._.js +3 -0
  234. package/.next/server/chunks/ssr/_0gmb3g_._.js.map +1 -0
  235. package/.next/server/chunks/ssr/_0okz9j8._.js +6 -0
  236. package/.next/server/chunks/ssr/_0okz9j8._.js.map +1 -0
  237. package/.next/server/chunks/ssr/_0wrbwro._.js +6 -0
  238. package/.next/server/chunks/ssr/_0wrbwro._.js.map +1 -0
  239. package/.next/server/chunks/ssr/node_modules_09w7yel._.js +33 -0
  240. package/.next/server/chunks/ssr/node_modules_09w7yel._.js.map +1 -0
  241. package/.next/server/chunks/ssr/node_modules_next_dist_0avqw4q._.js +3 -0
  242. package/.next/server/chunks/ssr/node_modules_next_dist_0avqw4q._.js.map +1 -0
  243. package/.next/server/chunks/ssr/node_modules_next_dist_0h9llsw._.js +6 -0
  244. package/.next/server/chunks/ssr/node_modules_next_dist_0h9llsw._.js.map +1 -0
  245. package/.next/server/chunks/ssr/node_modules_next_dist_0i_._k3._.js +3 -0
  246. package/.next/server/chunks/ssr/node_modules_next_dist_0i_._k3._.js.map +1 -0
  247. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0ee1czk._.js +3 -0
  248. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0ee1czk._.js.map +1 -0
  249. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0lgvd_..js +3 -0
  250. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0lgvd_..js.map +1 -0
  251. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js +3 -0
  252. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js.map +1 -0
  253. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0amzg6z.js +4 -0
  254. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0amzg6z.js.map +1 -0
  255. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dw1x0d.js +4 -0
  256. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dw1x0d.js.map +1 -0
  257. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0rc3ul_.js +4 -0
  258. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0rc3ul_.js.map +1 -0
  259. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10iomok.js +4 -0
  260. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10iomok.js.map +1 -0
  261. package/.next/server/chunks/ssr/packages_observer-dashboard_0~a2tmu._.js +3 -0
  262. package/.next/server/chunks/ssr/packages_observer-dashboard_0~a2tmu._.js.map +1 -0
  263. package/.next/server/chunks/ssr/packages_observer-dashboard_src_0f.ozc-._.js +3 -0
  264. package/.next/server/chunks/ssr/packages_observer-dashboard_src_0f.ozc-._.js.map +1 -0
  265. package/.next/server/chunks/ssr/packages_observer-dashboard_src_components_providers_tsx_03_vrrn._.js +7 -0
  266. package/.next/server/chunks/ssr/packages_observer-dashboard_src_components_providers_tsx_03_vrrn._.js.map +1 -0
  267. package/.next/server/functions-config-manifest.json +4 -0
  268. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  269. package/.next/server/middleware-build-manifest.js +23 -0
  270. package/.next/server/middleware-manifest.json +6 -0
  271. package/.next/server/next-font-manifest.js +1 -0
  272. package/.next/server/next-font-manifest.json +6 -0
  273. package/.next/server/pages/404.html +1 -0
  274. package/.next/server/pages/500.html +1 -0
  275. package/.next/server/pages-manifest.json +4 -0
  276. package/.next/server/prefetch-hints.json +1 -0
  277. package/.next/server/server-reference-manifest.js +1 -0
  278. package/.next/server/server-reference-manifest.json +24 -0
  279. package/.next/static/MvfPly4ZXHqaveDVOG1qq/_buildManifest.js +11 -0
  280. package/.next/static/MvfPly4ZXHqaveDVOG1qq/_clientMiddlewareManifest.js +1 -0
  281. package/.next/static/MvfPly4ZXHqaveDVOG1qq/_ssgManifest.js +1 -0
  282. package/.next/static/chunks/00c87uqn~kk2z.js +1 -0
  283. package/.next/static/chunks/01xlw8hd842-c.js +1 -0
  284. package/.next/static/chunks/02p9dpa.0oxiz.js +1 -0
  285. package/.next/static/chunks/034i63v_muq~d.js +1 -0
  286. package/.next/static/chunks/03mo-6~4pxdio.js +1 -0
  287. package/.next/static/chunks/03~yq9q893hmn.js +1 -0
  288. package/.next/static/chunks/04dm5qn77.fc2.js +1 -0
  289. package/.next/static/chunks/07uz2g0_38qia.js +4 -0
  290. package/.next/static/chunks/08nqnwvixoxnk.js +2 -0
  291. package/.next/static/chunks/0d3shmwh5_nmn.js +1 -0
  292. package/.next/static/chunks/0e_wyjw3nx.a..js +1 -0
  293. package/.next/static/chunks/0mstyq17cbf8-.js +1 -0
  294. package/.next/static/chunks/0ntuxw9.how-q.js +1 -0
  295. package/.next/static/chunks/0t3uzajv1qzmo.js +1 -0
  296. package/.next/static/chunks/0u~_nwr5-v.xp.js +1 -0
  297. package/.next/static/chunks/0wxcxh6eyzams.js +1 -0
  298. package/.next/static/chunks/0x6y7yt4kiddp.css +1 -0
  299. package/.next/static/chunks/0z6-vonyxr0dn.js +4 -0
  300. package/.next/static/chunks/0ze4gu236oq96.js +31 -0
  301. package/.next/static/chunks/0zwozael9msy1.js +1 -0
  302. package/.next/static/chunks/10qd__0r7a~.l.js +1 -0
  303. package/.next/static/chunks/11jh_u1ynmatg.js +1 -0
  304. package/.next/static/chunks/13xer3cb9shu-.js +5 -0
  305. package/.next/static/chunks/142zlnch_xmgd.js +1 -0
  306. package/.next/static/chunks/144kcri75qczu.js +1 -0
  307. package/.next/static/chunks/turbopack-0-ww6fe7b37qt.js +1 -0
  308. package/.next/static/media/icon.08ljfy7xai2x_.svg +20 -0
  309. package/LICENSE +21 -0
  310. package/README.md +490 -0
  311. package/next.config.mjs +25 -0
  312. package/package.json +104 -0
  313. package/postcss.config.mjs +8 -0
  314. package/src/app/actions/__tests__/approve-breakpoint.test.ts +246 -0
  315. package/src/app/actions/approve-breakpoint.ts +145 -0
  316. package/src/app/api/config/route.ts +137 -0
  317. package/src/app/api/digest/route.ts +45 -0
  318. package/src/app/api/runs/[runId]/events/route.ts +56 -0
  319. package/src/app/api/runs/[runId]/route.ts +84 -0
  320. package/src/app/api/runs/[runId]/tasks/[effectId]/route.ts +44 -0
  321. package/src/app/api/runs/route.ts +48 -0
  322. package/src/app/api/stream/route.ts +136 -0
  323. package/src/app/api/test/route.ts +1 -0
  324. package/src/app/api/version/route.ts +57 -0
  325. package/src/app/globals.css +555 -0
  326. package/src/app/icon.svg +20 -0
  327. package/src/app/layout.tsx +39 -0
  328. package/src/app/not-found.tsx +16 -0
  329. package/src/app/page.tsx +120 -0
  330. package/src/app/runs/[runId]/page.tsx +279 -0
  331. package/src/cli.ts +271 -0
  332. package/src/components/breakpoint/__tests__/breakpoint-approval.test.tsx +212 -0
  333. package/src/components/breakpoint/__tests__/breakpoint-panel.test.tsx +130 -0
  334. package/src/components/breakpoint/__tests__/file-preview.test.tsx +313 -0
  335. package/src/components/breakpoint/breakpoint-approval.tsx +138 -0
  336. package/src/components/breakpoint/breakpoint-panel.tsx +95 -0
  337. package/src/components/breakpoint/file-preview.tsx +215 -0
  338. package/src/components/dashboard/.gitkeep +0 -0
  339. package/src/components/dashboard/__tests__/breakpoint-banner.test.tsx +177 -0
  340. package/src/components/dashboard/__tests__/catch-up-banner.test.tsx +141 -0
  341. package/src/components/dashboard/__tests__/executive-summary-banner.test.tsx +164 -0
  342. package/src/components/dashboard/__tests__/kpi-grid.test.tsx +101 -0
  343. package/src/components/dashboard/__tests__/pagination-controls.test.tsx +125 -0
  344. package/src/components/dashboard/__tests__/project-accordion.test.tsx +97 -0
  345. package/src/components/dashboard/__tests__/project-list-view.test.tsx +174 -0
  346. package/src/components/dashboard/__tests__/project-search-input.test.tsx +110 -0
  347. package/src/components/dashboard/__tests__/project-section-header.test.tsx +91 -0
  348. package/src/components/dashboard/__tests__/project-section.test.tsx +151 -0
  349. package/src/components/dashboard/__tests__/run-card.test.tsx +164 -0
  350. package/src/components/dashboard/__tests__/run-filter-bar.test.tsx +109 -0
  351. package/src/components/dashboard/__tests__/run-list.test.tsx +123 -0
  352. package/src/components/dashboard/__tests__/search-filter.test.tsx +150 -0
  353. package/src/components/dashboard/__tests__/virtualized-run-list.test.tsx +179 -0
  354. package/src/components/dashboard/breakpoint-banner.tsx +301 -0
  355. package/src/components/dashboard/catch-up-banner.tsx +88 -0
  356. package/src/components/dashboard/executive-summary-banner.tsx +174 -0
  357. package/src/components/dashboard/global-search.tsx +323 -0
  358. package/src/components/dashboard/kpi-grid.tsx +140 -0
  359. package/src/components/dashboard/pagination-controls.tsx +100 -0
  360. package/src/components/dashboard/project-accordion.tsx +72 -0
  361. package/src/components/dashboard/project-health-card.tsx +536 -0
  362. package/src/components/dashboard/project-list-view.tsx +246 -0
  363. package/src/components/dashboard/project-search-input.tsx +41 -0
  364. package/src/components/dashboard/project-section-header.tsx +73 -0
  365. package/src/components/dashboard/project-section.tsx +89 -0
  366. package/src/components/dashboard/run-card.tsx +218 -0
  367. package/src/components/dashboard/run-filter-bar.tsx +100 -0
  368. package/src/components/dashboard/run-list.tsx +77 -0
  369. package/src/components/dashboard/search-filter.tsx +69 -0
  370. package/src/components/dashboard/virtualized-run-list.tsx +130 -0
  371. package/src/components/details/.gitkeep +0 -0
  372. package/src/components/details/__tests__/agent-panel.test.tsx +236 -0
  373. package/src/components/details/__tests__/json-tree.test.tsx +347 -0
  374. package/src/components/details/__tests__/log-viewer.test.tsx +168 -0
  375. package/src/components/details/__tests__/task-detail.test.tsx +212 -0
  376. package/src/components/details/__tests__/timing-panel.test.tsx +271 -0
  377. package/src/components/details/agent-panel.tsx +234 -0
  378. package/src/components/details/json-tree/categorize.ts +131 -0
  379. package/src/components/details/json-tree/index.tsx +120 -0
  380. package/src/components/details/json-tree/json-node.tsx +223 -0
  381. package/src/components/details/json-tree/smart-summary.tsx +596 -0
  382. package/src/components/details/json-tree/tree-controls.tsx +47 -0
  383. package/src/components/details/json-tree.tsx +9 -0
  384. package/src/components/details/log-viewer.tsx +140 -0
  385. package/src/components/details/task-detail.tsx +114 -0
  386. package/src/components/details/timing-panel.tsx +247 -0
  387. package/src/components/events/.gitkeep +0 -0
  388. package/src/components/events/__tests__/event-item.test.tsx +211 -0
  389. package/src/components/events/__tests__/event-stream.test.tsx +225 -0
  390. package/src/components/events/event-item.tsx +121 -0
  391. package/src/components/events/event-stream.tsx +260 -0
  392. package/src/components/notifications/.gitkeep +0 -0
  393. package/src/components/notifications/__tests__/notification-panel.test.tsx +287 -0
  394. package/src/components/notifications/__tests__/notification-provider.test.tsx +585 -0
  395. package/src/components/notifications/__tests__/toast-stack.test.tsx +217 -0
  396. package/src/components/notifications/notification-panel.tsx +124 -0
  397. package/src/components/notifications/notification-provider.tsx +175 -0
  398. package/src/components/notifications/toast-stack.tsx +75 -0
  399. package/src/components/pipeline/.gitkeep +0 -0
  400. package/src/components/pipeline/__tests__/parallel-group.test.tsx +88 -0
  401. package/src/components/pipeline/__tests__/pipeline-view.test.tsx +345 -0
  402. package/src/components/pipeline/__tests__/step-card.test.tsx +330 -0
  403. package/src/components/pipeline/parallel-group.tsx +39 -0
  404. package/src/components/pipeline/pipeline-view.tsx +197 -0
  405. package/src/components/pipeline/step-card.tsx +166 -0
  406. package/src/components/providers/event-stream-provider.tsx +29 -0
  407. package/src/components/providers.tsx +24 -0
  408. package/src/components/shared/.gitkeep +0 -0
  409. package/src/components/shared/__tests__/empty-state.test.tsx +49 -0
  410. package/src/components/shared/__tests__/friendly-id.test.tsx +47 -0
  411. package/src/components/shared/__tests__/kbd.test.tsx +45 -0
  412. package/src/components/shared/__tests__/kind-badge.test.tsx +71 -0
  413. package/src/components/shared/__tests__/metrics-row.test.tsx +74 -0
  414. package/src/components/shared/__tests__/outcome-banner.test.tsx +71 -0
  415. package/src/components/shared/__tests__/progress-bar.test.tsx +89 -0
  416. package/src/components/shared/__tests__/session-pill.test.tsx +62 -0
  417. package/src/components/shared/__tests__/settings-modal.test.tsx +201 -0
  418. package/src/components/shared/__tests__/shortcuts-help.test.tsx +103 -0
  419. package/src/components/shared/__tests__/status-badge.test.tsx +98 -0
  420. package/src/components/shared/__tests__/theme-provider.test.tsx +100 -0
  421. package/src/components/shared/__tests__/truncated-id.test.tsx +53 -0
  422. package/src/components/shared/app-footer.tsx +80 -0
  423. package/src/components/shared/app-header.tsx +160 -0
  424. package/src/components/shared/empty-state.tsx +18 -0
  425. package/src/components/shared/error-boundary.tsx +81 -0
  426. package/src/components/shared/friendly-id.tsx +48 -0
  427. package/src/components/shared/kbd.tsx +15 -0
  428. package/src/components/shared/kind-badge.tsx +51 -0
  429. package/src/components/shared/metrics-row.tsx +106 -0
  430. package/src/components/shared/outcome-banner.tsx +56 -0
  431. package/src/components/shared/progress-bar.tsx +42 -0
  432. package/src/components/shared/session-pill.tsx +69 -0
  433. package/src/components/shared/settings-modal.tsx +509 -0
  434. package/src/components/shared/shortcuts-help.tsx +113 -0
  435. package/src/components/shared/status-badge.tsx +110 -0
  436. package/src/components/shared/theme-provider.tsx +46 -0
  437. package/src/components/shared/truncated-id.tsx +51 -0
  438. package/src/components/ui/.gitkeep +0 -0
  439. package/src/components/ui/__tests__/accordion.test.tsx +96 -0
  440. package/src/components/ui/__tests__/badge.test.tsx +69 -0
  441. package/src/components/ui/__tests__/button.test.tsx +113 -0
  442. package/src/components/ui/__tests__/tabs.test.tsx +75 -0
  443. package/src/components/ui/__tests__/tooltip.test.tsx +90 -0
  444. package/src/components/ui/accordion.tsx +61 -0
  445. package/src/components/ui/badge.tsx +25 -0
  446. package/src/components/ui/button.tsx +40 -0
  447. package/src/components/ui/card.tsx +21 -0
  448. package/src/components/ui/scroll-area.tsx +35 -0
  449. package/src/components/ui/separator.tsx +24 -0
  450. package/src/components/ui/tabs.tsx +64 -0
  451. package/src/components/ui/tooltip.tsx +37 -0
  452. package/src/hooks/.gitkeep +0 -0
  453. package/src/hooks/__tests__/use-animated-number.test.ts +184 -0
  454. package/src/hooks/__tests__/use-batched-updates.test.ts +315 -0
  455. package/src/hooks/__tests__/use-event-stream.test.ts +243 -0
  456. package/src/hooks/__tests__/use-keyboard.test.ts +217 -0
  457. package/src/hooks/__tests__/use-notifications.test.ts +230 -0
  458. package/src/hooks/__tests__/use-polling.test.ts +274 -0
  459. package/src/hooks/__tests__/use-project-runs.test.ts +163 -0
  460. package/src/hooks/__tests__/use-projects.test.ts +248 -0
  461. package/src/hooks/__tests__/use-run-dashboard.test.ts +168 -0
  462. package/src/hooks/__tests__/use-run-detail.test.ts +273 -0
  463. package/src/hooks/__tests__/use-smart-polling.test.ts +305 -0
  464. package/src/hooks/use-animated-number.ts +87 -0
  465. package/src/hooks/use-batched-updates.ts +150 -0
  466. package/src/hooks/use-event-stream.ts +150 -0
  467. package/src/hooks/use-keyboard.ts +45 -0
  468. package/src/hooks/use-notifications.ts +82 -0
  469. package/src/hooks/use-persisted-state.ts +60 -0
  470. package/src/hooks/use-polling.ts +60 -0
  471. package/src/hooks/use-project-runs.ts +51 -0
  472. package/src/hooks/use-projects.ts +26 -0
  473. package/src/hooks/use-run-dashboard.ts +207 -0
  474. package/src/hooks/use-run-detail.ts +77 -0
  475. package/src/hooks/use-smart-polling.ts +144 -0
  476. package/src/lib/.gitkeep +0 -0
  477. package/src/lib/__tests__/cn.test.ts +69 -0
  478. package/src/lib/__tests__/config-loader.test.ts +210 -0
  479. package/src/lib/__tests__/config.test.ts +561 -0
  480. package/src/lib/__tests__/error-handler.test.ts +143 -0
  481. package/src/lib/__tests__/fetcher.test.ts +517 -0
  482. package/src/lib/__tests__/global-registry.test.ts +214 -0
  483. package/src/lib/__tests__/parser.test.ts +1532 -0
  484. package/src/lib/__tests__/path-resolver.test.ts +112 -0
  485. package/src/lib/__tests__/run-cache.test.ts +591 -0
  486. package/src/lib/__tests__/server-init.test.ts +512 -0
  487. package/src/lib/__tests__/source-discovery.test.ts +246 -0
  488. package/src/lib/__tests__/utils.test.ts +160 -0
  489. package/src/lib/__tests__/watcher.test.ts +227 -0
  490. package/src/lib/cn.ts +6 -0
  491. package/src/lib/config-loader.ts +195 -0
  492. package/src/lib/config.ts +20 -0
  493. package/src/lib/error-handler.ts +76 -0
  494. package/src/lib/fetcher.ts +394 -0
  495. package/src/lib/global-registry.ts +117 -0
  496. package/src/lib/parser.ts +794 -0
  497. package/src/lib/path-resolver.ts +16 -0
  498. package/src/lib/run-cache.ts +404 -0
  499. package/src/lib/server-init.ts +226 -0
  500. package/src/lib/services/__tests__/run-query-service.test.ts +819 -0
  501. package/src/lib/services/run-query-service.ts +286 -0
  502. package/src/lib/source-discovery.ts +216 -0
  503. package/src/lib/utils.ts +103 -0
  504. package/src/lib/watcher.ts +265 -0
  505. package/src/test/fixtures.ts +269 -0
  506. package/src/test/mocks/handlers.ts +110 -0
  507. package/src/test/mocks/server.ts +17 -0
  508. package/src/test/setup.ts +200 -0
  509. package/src/test/test-utils.tsx +36 -0
  510. package/src/types/.gitkeep +0 -0
  511. package/src/types/breakpoint.ts +17 -0
  512. package/src/types/index.ts +214 -0
  513. package/tsconfig.json +50 -0
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render, screen } from '@/test/test-utils';
4
+ import { MetricsRow } from '../metrics-row';
5
+ import { createMockRun, createMockTaskEffect } from '@/test/fixtures';
6
+
7
+ describe('MetricsRow', () => {
8
+ it('renders without crashing', () => {
9
+ const run = createMockRun();
10
+ render(<MetricsRow run={run} />);
11
+ expect(screen.getByText('Total Duration')).toBeInTheDocument();
12
+ });
13
+
14
+ it('displays task count as completed/total', () => {
15
+ const run = createMockRun({ completedTasks: 5, totalTasks: 10 });
16
+ render(<MetricsRow run={run} />);
17
+ expect(screen.getByText('5/10')).toBeInTheDocument();
18
+ });
19
+
20
+ it('displays the "Tasks" label', () => {
21
+ const run = createMockRun();
22
+ render(<MetricsRow run={run} />);
23
+ expect(screen.getByText('Tasks')).toBeInTheDocument();
24
+ });
25
+
26
+ it('displays the success rate percentage', () => {
27
+ const run = createMockRun({ completedTasks: 3, totalTasks: 4 });
28
+ render(<MetricsRow run={run} />);
29
+ expect(screen.getByText('75%')).toBeInTheDocument();
30
+ });
31
+
32
+ it('displays 0% success rate when there are no tasks', () => {
33
+ const run = createMockRun({ completedTasks: 0, totalTasks: 0, tasks: [] });
34
+ render(<MetricsRow run={run} />);
35
+ expect(screen.getByText('0%')).toBeInTheDocument();
36
+ });
37
+
38
+ it('displays 100% success rate when all tasks complete', () => {
39
+ const run = createMockRun({ completedTasks: 5, totalTasks: 5 });
40
+ render(<MetricsRow run={run} />);
41
+ expect(screen.getByText('100%')).toBeInTheDocument();
42
+ });
43
+
44
+ it('displays the "Success Rate" label', () => {
45
+ const run = createMockRun();
46
+ render(<MetricsRow run={run} />);
47
+ expect(screen.getByText('Success Rate')).toBeInTheDocument();
48
+ });
49
+
50
+ it('displays the iterations count', () => {
51
+ const run = createMockRun();
52
+ render(<MetricsRow run={run} />);
53
+ expect(screen.getByText('Iterations')).toBeInTheDocument();
54
+ });
55
+
56
+ it('counts unique invocationKeys for iterations', () => {
57
+ const tasks = [
58
+ createMockTaskEffect({ invocationKey: 'inv-1' }),
59
+ createMockTaskEffect({ invocationKey: 'inv-1' }),
60
+ createMockTaskEffect({ invocationKey: 'inv-2' }),
61
+ ];
62
+ const run = createMockRun({ tasks });
63
+ render(<MetricsRow run={run} />);
64
+ // 2 unique invocationKeys
65
+ expect(screen.getByText('2')).toBeInTheDocument();
66
+ });
67
+
68
+ it('displays formatted duration for completed run', () => {
69
+ const run = createMockRun({ status: 'completed', duration: 65000 });
70
+ render(<MetricsRow run={run} />);
71
+ // 65000ms = 1m 5s
72
+ expect(screen.getByText('1m 5s')).toBeInTheDocument();
73
+ });
74
+ });
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render, screen } from '@/test/test-utils';
4
+ import { OutcomeBanner } from '../outcome-banner';
5
+ import { createMockRun, createMockTaskEffect } from '@/test/fixtures';
6
+
7
+ describe('OutcomeBanner', () => {
8
+ it('renders nothing for pending status', () => {
9
+ const run = createMockRun({ status: 'pending' });
10
+ const { container } = render(<OutcomeBanner run={run} />);
11
+ expect(container.firstChild).toBeNull();
12
+ });
13
+
14
+ it('renders nothing for waiting status', () => {
15
+ const run = createMockRun({ status: 'waiting' });
16
+ const { container } = render(<OutcomeBanner run={run} />);
17
+ expect(container.firstChild).toBeNull();
18
+ });
19
+
20
+ it('renders completed banner with duration', () => {
21
+ const run = createMockRun({ status: 'completed', duration: 12000 });
22
+ render(<OutcomeBanner run={run} />);
23
+ expect(screen.getByText(/Completed in/)).toBeInTheDocument();
24
+ expect(screen.getByText(/12s/)).toBeInTheDocument();
25
+ });
26
+
27
+ it('renders failed banner with step name from failed task', () => {
28
+ const failedTask = createMockTaskEffect({
29
+ status: 'error',
30
+ label: 'run-ingest',
31
+ error: { name: 'Error', message: 'Connection timeout' },
32
+ });
33
+ const run = createMockRun({ status: 'failed', tasks: [failedTask] });
34
+ render(<OutcomeBanner run={run} />);
35
+ expect(screen.getByText(/Failed at step/)).toBeInTheDocument();
36
+ expect(screen.getByText(/run-ingest/)).toBeInTheDocument();
37
+ expect(screen.getByText(/Connection timeout/)).toBeInTheDocument();
38
+ });
39
+
40
+ it('renders failed banner with fallback step name from failedStep', () => {
41
+ const run = createMockRun({ status: 'failed', failedStep: 'step-x', tasks: [] });
42
+ render(<OutcomeBanner run={run} />);
43
+ expect(screen.getByText(/step-x/)).toBeInTheDocument();
44
+ });
45
+
46
+ it('renders failed banner with "unknown step" fallback', () => {
47
+ const run = createMockRun({ status: 'failed', tasks: [] });
48
+ render(<OutcomeBanner run={run} />);
49
+ expect(screen.getByText(/unknown step/)).toBeInTheDocument();
50
+ });
51
+
52
+ it('renders failed banner with fallback error message', () => {
53
+ const run = createMockRun({ status: 'failed', tasks: [] });
54
+ render(<OutcomeBanner run={run} />);
55
+ expect(screen.getByText(/An error occurred/)).toBeInTheDocument();
56
+ });
57
+
58
+ it('renders success icon for completed runs', () => {
59
+ const run = createMockRun({ status: 'completed', duration: 5000 });
60
+ const { container } = render(<OutcomeBanner run={run} />);
61
+ const svg = container.querySelector('svg');
62
+ expect(svg).toBeInTheDocument();
63
+ });
64
+
65
+ it('renders error icon for failed runs', () => {
66
+ const run = createMockRun({ status: 'failed', tasks: [] });
67
+ const { container } = render(<OutcomeBanner run={run} />);
68
+ const svg = container.querySelector('svg');
69
+ expect(svg).toBeInTheDocument();
70
+ });
71
+ });
@@ -0,0 +1,89 @@
1
+ import React from 'react';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render } from '@/test/test-utils';
4
+ import { ProgressBar } from '../progress-bar';
5
+
6
+ describe('ProgressBar', () => {
7
+ it('renders without crashing', () => {
8
+ const { container } = render(<ProgressBar value={50} />);
9
+ expect(container.firstChild).toBeInTheDocument();
10
+ });
11
+
12
+ it('renders 0% width when value is 0', () => {
13
+ const { container } = render(<ProgressBar value={0} />);
14
+ const bar = container.querySelector('[style]') as HTMLElement;
15
+ expect(bar.style.width).toBe('0%');
16
+ });
17
+
18
+ it('renders 50% width when value is 50', () => {
19
+ const { container } = render(<ProgressBar value={50} />);
20
+ const bar = container.querySelector('[style]') as HTMLElement;
21
+ expect(bar.style.width).toBe('50%');
22
+ });
23
+
24
+ it('renders 100% width when value is 100', () => {
25
+ const { container } = render(<ProgressBar value={100} />);
26
+ const bar = container.querySelector('[style]') as HTMLElement;
27
+ expect(bar.style.width).toBe('100%');
28
+ });
29
+
30
+ it('clamps value above 100 to 100%', () => {
31
+ const { container } = render(<ProgressBar value={150} />);
32
+ const bar = container.querySelector('[style]') as HTMLElement;
33
+ expect(bar.style.width).toBe('100%');
34
+ });
35
+
36
+ it('clamps negative value to 0%', () => {
37
+ const { container } = render(<ProgressBar value={-10} />);
38
+ const bar = container.querySelector('[style]') as HTMLElement;
39
+ expect(bar.style.width).toBe('0%');
40
+ });
41
+
42
+ it('applies rounded-full class when complete (100%)', () => {
43
+ const { container } = render(<ProgressBar value={100} />);
44
+ const bar = container.querySelector('[style]') as HTMLElement;
45
+ expect(bar.className).toContain('rounded-full');
46
+ });
47
+
48
+ it('applies rounded-l-full class when not complete', () => {
49
+ const { container } = render(<ProgressBar value={50} />);
50
+ const bar = container.querySelector('[style]') as HTMLElement;
51
+ expect(bar.className).toContain('rounded-l-full');
52
+ });
53
+
54
+ it('applies success variant styling', () => {
55
+ const { container } = render(<ProgressBar value={50} variant="success" />);
56
+ const bar = container.querySelector('[style]') as HTMLElement;
57
+ expect(bar.className).toContain('bg-success');
58
+ });
59
+
60
+ it('applies error variant styling', () => {
61
+ const { container } = render(<ProgressBar value={50} variant="error" />);
62
+ const bar = container.querySelector('[style]') as HTMLElement;
63
+ expect(bar.className).toContain('bg-error');
64
+ });
65
+
66
+ it('applies warning variant styling', () => {
67
+ const { container } = render(<ProgressBar value={50} variant="warning" />);
68
+ const bar = container.querySelector('[style]') as HTMLElement;
69
+ expect(bar.className).toContain('bg-warning');
70
+ });
71
+
72
+ it('applies glow classes when glow is true', () => {
73
+ const { container } = render(<ProgressBar value={50} glow />);
74
+ const bar = container.querySelector('[style]') as HTMLElement;
75
+ expect(bar.className).toContain('shadow-progress-glow-primary');
76
+ });
77
+
78
+ it('does not apply glow classes when glow is false', () => {
79
+ const { container } = render(<ProgressBar value={50} glow={false} />);
80
+ const bar = container.querySelector('[style]') as HTMLElement;
81
+ expect(bar.className).not.toContain('shadow-progress-glow');
82
+ });
83
+
84
+ it('applies custom className to outer container', () => {
85
+ const { container } = render(<ProgressBar value={50} className="my-class" />);
86
+ const outer = container.firstChild as HTMLElement;
87
+ expect(outer.className).toContain('my-class');
88
+ });
89
+ });
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen } from '@/test/test-utils';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { SessionPill } from '../session-pill';
6
+
7
+ describe('SessionPill', () => {
8
+ it('renders nothing when sessionId is undefined', () => {
9
+ const { container } = render(<SessionPill />);
10
+ expect(container.firstChild).toBeNull();
11
+ });
12
+
13
+ it('renders nothing when sessionId is empty string', () => {
14
+ const { container } = render(<SessionPill sessionId="" />);
15
+ expect(container.firstChild).toBeNull();
16
+ });
17
+
18
+ it('renders the truncated session ID', () => {
19
+ render(<SessionPill sessionId="abcdef123456" />);
20
+ // formatShortId with chars=4 produces "...3456"
21
+ expect(screen.getByText('...3456')).toBeInTheDocument();
22
+ });
23
+
24
+ it('renders an active state indicator dot', () => {
25
+ const { container } = render(<SessionPill sessionId="abcdef123456" active />);
26
+ // The active dot should have animate-pulse-dot class
27
+ const dots = container.querySelectorAll('span span');
28
+ const activeDot = Array.from(dots).find(el => el.className.includes('animate-pulse-dot'));
29
+ expect(activeDot).toBeTruthy();
30
+ });
31
+
32
+ it('renders an inactive state indicator dot', () => {
33
+ const { container } = render(<SessionPill sessionId="abcdef123456" active={false} />);
34
+ const dots = container.querySelectorAll('span span');
35
+ const inactiveDot = Array.from(dots).find(el => el.className.includes('bg-foreground-muted/40'));
36
+ expect(inactiveDot).toBeTruthy();
37
+ });
38
+
39
+ it('copies session ID to clipboard on click', async () => {
40
+ const user = userEvent.setup();
41
+ const writeTextSpy = vi.spyOn(navigator.clipboard, 'writeText');
42
+ render(<SessionPill sessionId="session-xyz-12345" />);
43
+ const pill = screen.getByText('...2345');
44
+ await user.click(pill);
45
+ expect(writeTextSpy).toHaveBeenCalledWith('session-xyz-12345');
46
+ });
47
+
48
+ it('shows "Copied!" feedback after click', async () => {
49
+ const user = userEvent.setup();
50
+ render(<SessionPill sessionId="session-xyz-12345" />);
51
+ const pill = screen.getByText('...2345');
52
+ await user.click(pill);
53
+ expect(screen.getByText('Copied!')).toBeInTheDocument();
54
+ });
55
+
56
+ it('applies custom className', () => {
57
+ const { container } = render(<SessionPill sessionId="abc123" className="extra" />);
58
+ // Find the main span trigger
59
+ const span = container.querySelector('span');
60
+ expect(span).toBeTruthy();
61
+ });
62
+ });
@@ -0,0 +1,201 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ import { render, screen, waitFor } from '@/test/test-utils';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { SettingsModal } from '../settings-modal';
6
+ import { ThemeProvider } from '../theme-provider';
7
+
8
+ const mockConfig = {
9
+ sources: [{ path: '/tmp/runs', depth: 2, label: 'test' }],
10
+ port: 4040,
11
+ pollInterval: 2000,
12
+ theme: 'dark' as const,
13
+ retentionDays: 30,
14
+ hiddenProjects: [],
15
+ };
16
+
17
+ const mockProjects = { projects: [{ projectName: 'test-project' }] };
18
+
19
+ /** Create a proper Response for resilientFetch from JSON data */
20
+ function jsonResponse(data: unknown): Response {
21
+ return new Response(JSON.stringify(data), {
22
+ status: 200,
23
+ headers: { 'Content-Type': 'application/json' },
24
+ });
25
+ }
26
+
27
+ /**
28
+ * Mock fetch for SettingsModal which makes 2 parallel requests:
29
+ * 1. GET /api/config
30
+ * 2. GET /api/runs?mode=projects
31
+ */
32
+ function mockSettingsFetch() {
33
+ vi.spyOn(globalThis, 'fetch').mockImplementation((input: RequestInfo | URL) => {
34
+ const url = typeof input === 'string' ? input : input.toString();
35
+ if (url.includes('/api/config')) {
36
+ return Promise.resolve(jsonResponse(mockConfig));
37
+ }
38
+ if (url.includes('/api/runs')) {
39
+ return Promise.resolve(jsonResponse(mockProjects));
40
+ }
41
+ return Promise.resolve(new Response('Not Found', { status: 404 }));
42
+ });
43
+ }
44
+
45
+ function renderWithTheme(open: boolean, onClose = vi.fn()) {
46
+ return render(
47
+ <ThemeProvider>
48
+ <SettingsModal open={open} onClose={onClose} />
49
+ </ThemeProvider>,
50
+ );
51
+ }
52
+
53
+ describe('SettingsModal', () => {
54
+ beforeEach(() => {
55
+ vi.restoreAllMocks();
56
+ });
57
+
58
+ it('renders nothing when open is false', () => {
59
+ const { container } = renderWithTheme(false);
60
+ expect(container.querySelector('[class*="fixed"]')).toBeNull();
61
+ });
62
+
63
+ it('renders modal when open is true and config loads', async () => {
64
+ mockSettingsFetch();
65
+
66
+ renderWithTheme(true);
67
+
68
+ await waitFor(() => {
69
+ expect(screen.getByText('Settings')).toBeInTheDocument();
70
+ });
71
+ });
72
+
73
+ it('shows loading indicator while fetching config', () => {
74
+ // Never resolve fetch
75
+ vi.spyOn(globalThis, 'fetch').mockReturnValue(new Promise(() => {}));
76
+
77
+ renderWithTheme(true);
78
+
79
+ expect(screen.getByText('Loading configuration...')).toBeInTheDocument();
80
+ });
81
+
82
+ it('shows fetch error when config load fails', async () => {
83
+ vi.spyOn(globalThis, 'fetch').mockImplementation((input: RequestInfo | URL) => {
84
+ const url = typeof input === 'string' ? input : input.toString();
85
+ if (url.includes('/api/config')) {
86
+ return Promise.resolve(new Response('Bad request', { status: 400 }));
87
+ }
88
+ if (url.includes('/api/runs')) {
89
+ return Promise.resolve(jsonResponse(mockProjects));
90
+ }
91
+ return Promise.resolve(new Response('Not Found', { status: 404 }));
92
+ });
93
+
94
+ renderWithTheme(true);
95
+
96
+ await waitFor(() => {
97
+ expect(screen.getByText(/Failed to load config/)).toBeInTheDocument();
98
+ });
99
+ });
100
+
101
+ it('displays watch sources section after config loads', async () => {
102
+ mockSettingsFetch();
103
+
104
+ renderWithTheme(true);
105
+
106
+ await waitFor(() => {
107
+ expect(screen.getByText('Watch Sources')).toBeInTheDocument();
108
+ });
109
+ });
110
+
111
+ it('displays poll interval section after config loads', async () => {
112
+ mockSettingsFetch();
113
+
114
+ renderWithTheme(true);
115
+
116
+ await waitFor(() => {
117
+ expect(screen.getByText('Poll Interval')).toBeInTheDocument();
118
+ });
119
+ });
120
+
121
+ it('displays theme section after config loads', async () => {
122
+ mockSettingsFetch();
123
+
124
+ renderWithTheme(true);
125
+
126
+ await waitFor(() => {
127
+ expect(screen.getByText('Theme')).toBeInTheDocument();
128
+ });
129
+ });
130
+
131
+ it('calls onClose when clicking the close button', async () => {
132
+ const user = userEvent.setup();
133
+ const onClose = vi.fn();
134
+ mockSettingsFetch();
135
+
136
+ render(
137
+ <ThemeProvider>
138
+ <SettingsModal open={true} onClose={onClose} />
139
+ </ThemeProvider>,
140
+ );
141
+
142
+ await waitFor(() => {
143
+ expect(screen.getByText('Settings')).toBeInTheDocument();
144
+ });
145
+
146
+ // Click the X close button (the button adjacent to the header)
147
+ const closeButtons = screen.getAllByRole('button');
148
+ // First button should be the X close button
149
+ const xButton = closeButtons[0];
150
+ await user.click(xButton);
151
+ expect(onClose).toHaveBeenCalled();
152
+ });
153
+
154
+ it('calls onClose when pressing Escape', async () => {
155
+ const onClose = vi.fn();
156
+ mockSettingsFetch();
157
+
158
+ render(
159
+ <ThemeProvider>
160
+ <SettingsModal open={true} onClose={onClose} />
161
+ </ThemeProvider>,
162
+ );
163
+
164
+ await waitFor(() => {
165
+ expect(screen.getByText('Settings')).toBeInTheDocument();
166
+ });
167
+
168
+ // Radix Dialog listens for Escape on the document
169
+ const event = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true });
170
+ document.dispatchEvent(event);
171
+
172
+ expect(onClose).toHaveBeenCalled();
173
+ });
174
+
175
+ it('shows Add Source button and can add a new source', async () => {
176
+ const user = userEvent.setup();
177
+ mockSettingsFetch();
178
+
179
+ renderWithTheme(true);
180
+
181
+ await waitFor(() => {
182
+ expect(screen.getByText('Add Source')).toBeInTheDocument();
183
+ });
184
+
185
+ await user.click(screen.getByText('Add Source'));
186
+
187
+ // There should now be 2 source path inputs (original + new)
188
+ const pathInputs = screen.getAllByPlaceholderText('/path/to/projects');
189
+ expect(pathInputs.length).toBe(2);
190
+ });
191
+
192
+ it('shows config file path in footer', async () => {
193
+ mockSettingsFetch();
194
+
195
+ renderWithTheme(true);
196
+
197
+ await waitFor(() => {
198
+ expect(screen.getByText('~/.a5c/observer.json')).toBeInTheDocument();
199
+ });
200
+ });
201
+ });
@@ -0,0 +1,103 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen, fireEvent } from '@/test/test-utils';
4
+ import { ShortcutsHelp } from '../shortcuts-help';
5
+
6
+ // Default mock returns '/' (dashboard). Override per-test for run detail.
7
+ const mockUsePathname = vi.fn(() => '/');
8
+ vi.mock('next/navigation', async () => {
9
+ const actual = await vi.importActual('next/navigation');
10
+ return { ...actual, usePathname: () => mockUsePathname() };
11
+ });
12
+
13
+ describe('ShortcutsHelp', () => {
14
+ it('renders nothing initially (modal is closed)', () => {
15
+ render(<ShortcutsHelp />);
16
+ expect(screen.queryByText('Keyboard Shortcuts')).not.toBeInTheDocument();
17
+ });
18
+
19
+ it('opens modal on "?" key press', () => {
20
+ render(<ShortcutsHelp />);
21
+ fireEvent.keyDown(window, { key: '?' });
22
+ expect(screen.getByText('Keyboard Shortcuts')).toBeInTheDocument();
23
+ });
24
+
25
+ it('on dashboard, shows only global and dashboard shortcuts', () => {
26
+ mockUsePathname.mockReturnValue('/');
27
+ render(<ShortcutsHelp />);
28
+ fireEvent.keyDown(window, { key: '?' });
29
+
30
+ // Global shortcuts
31
+ expect(screen.getByText('Show this help')).toBeInTheDocument();
32
+ expect(screen.getByText('Toggle notifications')).toBeInTheDocument();
33
+ // Dashboard shortcuts
34
+ expect(screen.getByText('Focus search')).toBeInTheDocument();
35
+ // Run-detail shortcuts should NOT appear
36
+ expect(screen.queryByText('Next item')).not.toBeInTheDocument();
37
+ expect(screen.queryByText('Agent tab')).not.toBeInTheDocument();
38
+ });
39
+
40
+ it('on run detail page, shows global and run-detail shortcuts', () => {
41
+ mockUsePathname.mockReturnValue('/runs/abc-123');
42
+ render(<ShortcutsHelp />);
43
+ fireEvent.keyDown(window, { key: '?' });
44
+
45
+ // Global shortcuts
46
+ expect(screen.getByText('Show this help')).toBeInTheDocument();
47
+ expect(screen.getByText('Toggle notifications')).toBeInTheDocument();
48
+ // Run-detail shortcuts
49
+ expect(screen.getByText('Next item')).toBeInTheDocument();
50
+ expect(screen.getByText('Previous item')).toBeInTheDocument();
51
+ expect(screen.getByText('Open selected')).toBeInTheDocument();
52
+ expect(screen.getByText('Go back / Close')).toBeInTheDocument();
53
+ expect(screen.getByText('Toggle event stream')).toBeInTheDocument();
54
+ expect(screen.getByText('Agent tab')).toBeInTheDocument();
55
+ expect(screen.getByText('Timing tab')).toBeInTheDocument();
56
+ expect(screen.getByText('Logs tab')).toBeInTheDocument();
57
+ expect(screen.getByText('Data tab')).toBeInTheDocument();
58
+ expect(screen.getByText('Approval tab')).toBeInTheDocument();
59
+ // Dashboard shortcuts should NOT appear
60
+ expect(screen.queryByText('Focus search')).not.toBeInTheDocument();
61
+ });
62
+
63
+ it('displays keyboard keys when open', () => {
64
+ mockUsePathname.mockReturnValue('/runs/abc-123');
65
+ render(<ShortcutsHelp />);
66
+ fireEvent.keyDown(window, { key: '?' });
67
+
68
+ expect(screen.getByText('j')).toBeInTheDocument();
69
+ expect(screen.getByText('k')).toBeInTheDocument();
70
+ expect(screen.getByText('Enter')).toBeInTheDocument();
71
+ expect(screen.getByText('Esc')).toBeInTheDocument();
72
+ });
73
+
74
+ it('shows section headers', () => {
75
+ mockUsePathname.mockReturnValue('/runs/abc-123');
76
+ render(<ShortcutsHelp />);
77
+ fireEvent.keyDown(window, { key: '?' });
78
+
79
+ expect(screen.getByText('Global')).toBeInTheDocument();
80
+ expect(screen.getByText('Run Detail')).toBeInTheDocument();
81
+ });
82
+
83
+ it('closes modal on Escape key press', () => {
84
+ render(<ShortcutsHelp />);
85
+ // Open
86
+ fireEvent.keyDown(window, { key: '?' });
87
+ expect(screen.getByText('Keyboard Shortcuts')).toBeInTheDocument();
88
+ // Close
89
+ fireEvent.keyDown(window, { key: 'Escape' });
90
+ expect(screen.queryByText('Keyboard Shortcuts')).not.toBeInTheDocument();
91
+ });
92
+
93
+ it('closes modal when clicking the close button', async () => {
94
+ render(<ShortcutsHelp />);
95
+ fireEvent.keyDown(window, { key: '?' });
96
+ expect(screen.getByText('Keyboard Shortcuts')).toBeInTheDocument();
97
+
98
+ // Click the close button (the X button) - find it via the Dialog.Close wrapping
99
+ const closeButton = screen.getByTestId('icon-X').closest('button')!;
100
+ fireEvent.click(closeButton);
101
+ expect(screen.queryByText('Keyboard Shortcuts')).not.toBeInTheDocument();
102
+ });
103
+ });