@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.
- package/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +16 -0
- package/.next/build-manifest.json +23 -0
- package/.next/export-marker.json +6 -0
- package/.next/fallback-build-manifest.json +13 -0
- package/.next/images-manifest.json +68 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +114 -0
- package/.next/required-server-files.json +334 -0
- package/.next/routes-manifest.json +139 -0
- package/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
- package/.next/server/app/_global-error/page/build-manifest.json +19 -0
- package/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
- package/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
- package/.next/server/app/_global-error/page.js +9 -0
- package/.next/server/app/_global-error/page.js.map +5 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
- package/.next/server/app/_global-error.html +1 -0
- package/.next/server/app/_global-error.meta +15 -0
- package/.next/server/app/_global-error.rsc +14 -0
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
- package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
- package/.next/server/app/_not-found/page/build-manifest.json +19 -0
- package/.next/server/app/_not-found/page/next-font-manifest.json +6 -0
- package/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
- package/.next/server/app/_not-found/page.js +13 -0
- package/.next/server/app/_not-found/page.js.map +5 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
- package/.next/server/app/_not-found.html +1 -0
- package/.next/server/app/_not-found.meta +16 -0
- package/.next/server/app/_not-found.rsc +19 -0
- package/.next/server/app/_not-found.segments/_full.segment.rsc +19 -0
- package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
- package/.next/server/app/api/config/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/config/route/build-manifest.json +9 -0
- package/.next/server/app/api/config/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/config/route.js +8 -0
- package/.next/server/app/api/config/route.js.map +5 -0
- package/.next/server/app/api/config/route.js.nft.json +1 -0
- package/.next/server/app/api/config/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/digest/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/digest/route/build-manifest.json +9 -0
- package/.next/server/app/api/digest/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/digest/route.js +9 -0
- package/.next/server/app/api/digest/route.js.map +5 -0
- package/.next/server/app/api/digest/route.js.nft.json +1 -0
- package/.next/server/app/api/digest/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/runs/[runId]/events/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/runs/[runId]/events/route/build-manifest.json +9 -0
- package/.next/server/app/api/runs/[runId]/events/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/runs/[runId]/events/route.js +8 -0
- package/.next/server/app/api/runs/[runId]/events/route.js.map +5 -0
- package/.next/server/app/api/runs/[runId]/events/route.js.nft.json +1 -0
- package/.next/server/app/api/runs/[runId]/events/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/runs/[runId]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/runs/[runId]/route/build-manifest.json +9 -0
- package/.next/server/app/api/runs/[runId]/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/runs/[runId]/route.js +9 -0
- package/.next/server/app/api/runs/[runId]/route.js.map +5 -0
- package/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -0
- package/.next/server/app/api/runs/[runId]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/build-manifest.json +9 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js +8 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js.map +5 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route.js.nft.json +1 -0
- package/.next/server/app/api/runs/[runId]/tasks/[effectId]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/runs/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/runs/route/build-manifest.json +9 -0
- package/.next/server/app/api/runs/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/runs/route.js +9 -0
- package/.next/server/app/api/runs/route.js.map +5 -0
- package/.next/server/app/api/runs/route.js.nft.json +1 -0
- package/.next/server/app/api/runs/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/stream/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/stream/route/build-manifest.json +9 -0
- package/.next/server/app/api/stream/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/stream/route.js +8 -0
- package/.next/server/app/api/stream/route.js.map +5 -0
- package/.next/server/app/api/stream/route.js.nft.json +1 -0
- package/.next/server/app/api/stream/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/test/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/test/route/build-manifest.json +9 -0
- package/.next/server/app/api/test/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/test/route.js +6 -0
- package/.next/server/app/api/test/route.js.map +5 -0
- package/.next/server/app/api/test/route.js.nft.json +1 -0
- package/.next/server/app/api/test/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/version/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/version/route/build-manifest.json +9 -0
- package/.next/server/app/api/version/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/version/route.js +7 -0
- package/.next/server/app/api/version/route.js.map +5 -0
- package/.next/server/app/api/version/route.js.nft.json +1 -0
- package/.next/server/app/api/version/route_client-reference-manifest.js +3 -0
- package/.next/server/app/icon.svg/route/app-paths-manifest.json +3 -0
- package/.next/server/app/icon.svg/route/build-manifest.json +9 -0
- package/.next/server/app/icon.svg/route.js +7 -0
- package/.next/server/app/icon.svg/route.js.map +5 -0
- package/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/.next/server/app/icon.svg.body +20 -0
- package/.next/server/app/icon.svg.meta +1 -0
- package/.next/server/app/index.html +1 -0
- package/.next/server/app/index.meta +14 -0
- package/.next/server/app/index.rsc +21 -0
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/index.segments/_full.segment.rsc +21 -0
- package/.next/server/app/index.segments/_head.segment.rsc +6 -0
- package/.next/server/app/index.segments/_index.segment.rsc +8 -0
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -0
- package/.next/server/app/page/app-paths-manifest.json +3 -0
- package/.next/server/app/page/build-manifest.json +19 -0
- package/.next/server/app/page/next-font-manifest.json +6 -0
- package/.next/server/app/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/page/server-reference-manifest.json +17 -0
- package/.next/server/app/page.js +15 -0
- package/.next/server/app/page.js.map +5 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +3 -0
- package/.next/server/app/runs/[runId]/page/app-paths-manifest.json +3 -0
- package/.next/server/app/runs/[runId]/page/build-manifest.json +19 -0
- package/.next/server/app/runs/[runId]/page/next-font-manifest.json +6 -0
- package/.next/server/app/runs/[runId]/page/react-loadable-manifest.json +22 -0
- package/.next/server/app/runs/[runId]/page/server-reference-manifest.json +17 -0
- package/.next/server/app/runs/[runId]/page.js +15 -0
- package/.next/server/app/runs/[runId]/page.js.map +5 -0
- package/.next/server/app/runs/[runId]/page.js.nft.json +1 -0
- package/.next/server/app/runs/[runId]/page_client-reference-manifest.js +3 -0
- package/.next/server/app-paths-manifest.json +16 -0
- package/.next/server/chunks/01oi_server_app_api_runs_[runId]_tasks_[effectId]_route_actions_0r72yai.js +3 -0
- package/.next/server/chunks/01oi_server_app_api_runs_[runId]_tasks_[effectId]_route_actions_0r72yai.js.map +1 -0
- package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_events_route_actions_0~msldk.js +3 -0
- package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_events_route_actions_0~msldk.js.map +1 -0
- package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_route_actions_09iz0n6.js +3 -0
- package/.next/server/chunks/0h.v__next-internal_server_app_api_runs_[runId]_route_actions_09iz0n6.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_config_route_actions_0~eypoa.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_config_route_actions_0~eypoa.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_digest_route_actions_04jj5zs.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_digest_route_actions_04jj5zs.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_runs_route_actions_0~-t-o4.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_runs_route_actions_0~-t-o4.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_stream_route_actions_0fkmv2_.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_stream_route_actions_0fkmv2_.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_test_route_actions_00ugava.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_test_route_actions_00ugava.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_version_route_actions_0~v3ojm.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_api_version_route_actions_0~v3ojm.js.map +1 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_icon_svg_route_actions_0yypxkm.js +3 -0
- package/.next/server/chunks/0juq_observer-dashboard__next-internal_server_app_icon_svg_route_actions_0yypxkm.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0.6bt.6._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0.6bt.6._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__08kwev1._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__08kwev1._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__096el.d._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__096el.d._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0_bmt4z._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0_bmt4z._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0_ln2d2._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0_ln2d2._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0al3v65._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0al3v65._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0gf516b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0gf516b._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0kdfw4x._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0kdfw4x._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0pxt00h._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0pxt00h._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0rubnza._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0rubnza._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0tn9iud._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0tn9iud._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0ws5o6i._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ws5o6i._.js.map +1 -0
- package/.next/server/chunks/[turbopack]_runtime.js +903 -0
- package/.next/server/chunks/[turbopack]_runtime.js.map +11 -0
- package/.next/server/chunks/node_modules_next_04~_e52._.js +13 -0
- package/.next/server/chunks/node_modules_next_04~_e52._.js.map +1 -0
- package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js +9 -0
- package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js.map +1 -0
- package/.next/server/chunks/packages_observer-dashboard_src_lib_02.vvb.._.js +3 -0
- package/.next/server/chunks/packages_observer-dashboard_src_lib_02.vvb.._.js.map +1 -0
- package/.next/server/chunks/packages_observer-dashboard_src_lib_0rqgpk0._.js +3 -0
- package/.next/server/chunks/packages_observer-dashboard_src_lib_0rqgpk0._.js.map +1 -0
- package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__global-error_page_actions_0ekoxmy.js +3 -0
- package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__global-error_page_actions_0ekoxmy.js.map +1 -0
- package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__not-found_page_actions_09b3ti3.js +3 -0
- package/.next/server/chunks/ssr/0juq_observer-dashboard__next-internal_server_app__not-found_page_actions_09b3ti3.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__006f7~t._.js +4 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__006f7~t._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__02jgvbi._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__02jgvbi._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__04j8t~1._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__04j8t~1._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09c~s.0._.js +33 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09c~s.0._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0cpy61n._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0cpy61n._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0cwa32j._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0cwa32j._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0fk_g0j._.js +19 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0fk_g0j._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0pddpic._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0pddpic._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0pvtneq._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0pvtneq._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0xc-2vm._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0xc-2vm._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js +33 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js.map +1 -0
- package/.next/server/chunks/ssr/[turbopack]_runtime.js +903 -0
- package/.next/server/chunks/ssr/[turbopack]_runtime.js.map +11 -0
- package/.next/server/chunks/ssr/_00yo1im._.js +3 -0
- package/.next/server/chunks/ssr/_00yo1im._.js.map +1 -0
- package/.next/server/chunks/ssr/_03sbc.o._.js +3 -0
- package/.next/server/chunks/ssr/_03sbc.o._.js.map +1 -0
- package/.next/server/chunks/ssr/_04z5ea0._.js +3 -0
- package/.next/server/chunks/ssr/_04z5ea0._.js.map +1 -0
- package/.next/server/chunks/ssr/_0gmb3g_._.js +3 -0
- package/.next/server/chunks/ssr/_0gmb3g_._.js.map +1 -0
- package/.next/server/chunks/ssr/_0okz9j8._.js +6 -0
- package/.next/server/chunks/ssr/_0okz9j8._.js.map +1 -0
- package/.next/server/chunks/ssr/_0wrbwro._.js +6 -0
- package/.next/server/chunks/ssr/_0wrbwro._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_09w7yel._.js +33 -0
- package/.next/server/chunks/ssr/node_modules_09w7yel._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0avqw4q._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0avqw4q._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0h9llsw._.js +6 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0h9llsw._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0i_._k3._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_0i_._k3._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0ee1czk._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0ee1czk._.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0lgvd_..js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0lgvd_..js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js +3 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0amzg6z.js +4 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0amzg6z.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dw1x0d.js +4 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dw1x0d.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0rc3ul_.js +4 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0rc3ul_.js.map +1 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10iomok.js +4 -0
- package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10iomok.js.map +1 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_0~a2tmu._.js +3 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_0~a2tmu._.js.map +1 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_src_0f.ozc-._.js +3 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_src_0f.ozc-._.js.map +1 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_src_components_providers_tsx_03_vrrn._.js +7 -0
- package/.next/server/chunks/ssr/packages_observer-dashboard_src_components_providers_tsx_03_vrrn._.js.map +1 -0
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +23 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +6 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages-manifest.json +4 -0
- package/.next/server/prefetch-hints.json +1 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +24 -0
- package/.next/static/MvfPly4ZXHqaveDVOG1qq/_buildManifest.js +11 -0
- package/.next/static/MvfPly4ZXHqaveDVOG1qq/_clientMiddlewareManifest.js +1 -0
- package/.next/static/MvfPly4ZXHqaveDVOG1qq/_ssgManifest.js +1 -0
- package/.next/static/chunks/00c87uqn~kk2z.js +1 -0
- package/.next/static/chunks/01xlw8hd842-c.js +1 -0
- package/.next/static/chunks/02p9dpa.0oxiz.js +1 -0
- package/.next/static/chunks/034i63v_muq~d.js +1 -0
- package/.next/static/chunks/03mo-6~4pxdio.js +1 -0
- package/.next/static/chunks/03~yq9q893hmn.js +1 -0
- package/.next/static/chunks/04dm5qn77.fc2.js +1 -0
- package/.next/static/chunks/07uz2g0_38qia.js +4 -0
- package/.next/static/chunks/08nqnwvixoxnk.js +2 -0
- package/.next/static/chunks/0d3shmwh5_nmn.js +1 -0
- package/.next/static/chunks/0e_wyjw3nx.a..js +1 -0
- package/.next/static/chunks/0mstyq17cbf8-.js +1 -0
- package/.next/static/chunks/0ntuxw9.how-q.js +1 -0
- package/.next/static/chunks/0t3uzajv1qzmo.js +1 -0
- package/.next/static/chunks/0u~_nwr5-v.xp.js +1 -0
- package/.next/static/chunks/0wxcxh6eyzams.js +1 -0
- package/.next/static/chunks/0x6y7yt4kiddp.css +1 -0
- package/.next/static/chunks/0z6-vonyxr0dn.js +4 -0
- package/.next/static/chunks/0ze4gu236oq96.js +31 -0
- package/.next/static/chunks/0zwozael9msy1.js +1 -0
- package/.next/static/chunks/10qd__0r7a~.l.js +1 -0
- package/.next/static/chunks/11jh_u1ynmatg.js +1 -0
- package/.next/static/chunks/13xer3cb9shu-.js +5 -0
- package/.next/static/chunks/142zlnch_xmgd.js +1 -0
- package/.next/static/chunks/144kcri75qczu.js +1 -0
- package/.next/static/chunks/turbopack-0-ww6fe7b37qt.js +1 -0
- package/.next/static/media/icon.08ljfy7xai2x_.svg +20 -0
- package/LICENSE +21 -0
- package/README.md +490 -0
- package/next.config.mjs +25 -0
- package/package.json +104 -0
- package/postcss.config.mjs +8 -0
- package/src/app/actions/__tests__/approve-breakpoint.test.ts +246 -0
- package/src/app/actions/approve-breakpoint.ts +145 -0
- package/src/app/api/config/route.ts +137 -0
- package/src/app/api/digest/route.ts +45 -0
- package/src/app/api/runs/[runId]/events/route.ts +56 -0
- package/src/app/api/runs/[runId]/route.ts +84 -0
- package/src/app/api/runs/[runId]/tasks/[effectId]/route.ts +44 -0
- package/src/app/api/runs/route.ts +48 -0
- package/src/app/api/stream/route.ts +136 -0
- package/src/app/api/test/route.ts +1 -0
- package/src/app/api/version/route.ts +57 -0
- package/src/app/globals.css +555 -0
- package/src/app/icon.svg +20 -0
- package/src/app/layout.tsx +39 -0
- package/src/app/not-found.tsx +16 -0
- package/src/app/page.tsx +120 -0
- package/src/app/runs/[runId]/page.tsx +279 -0
- package/src/cli.ts +271 -0
- package/src/components/breakpoint/__tests__/breakpoint-approval.test.tsx +212 -0
- package/src/components/breakpoint/__tests__/breakpoint-panel.test.tsx +130 -0
- package/src/components/breakpoint/__tests__/file-preview.test.tsx +313 -0
- package/src/components/breakpoint/breakpoint-approval.tsx +138 -0
- package/src/components/breakpoint/breakpoint-panel.tsx +95 -0
- package/src/components/breakpoint/file-preview.tsx +215 -0
- package/src/components/dashboard/.gitkeep +0 -0
- package/src/components/dashboard/__tests__/breakpoint-banner.test.tsx +177 -0
- package/src/components/dashboard/__tests__/catch-up-banner.test.tsx +141 -0
- package/src/components/dashboard/__tests__/executive-summary-banner.test.tsx +164 -0
- package/src/components/dashboard/__tests__/kpi-grid.test.tsx +101 -0
- package/src/components/dashboard/__tests__/pagination-controls.test.tsx +125 -0
- package/src/components/dashboard/__tests__/project-accordion.test.tsx +97 -0
- package/src/components/dashboard/__tests__/project-list-view.test.tsx +174 -0
- package/src/components/dashboard/__tests__/project-search-input.test.tsx +110 -0
- package/src/components/dashboard/__tests__/project-section-header.test.tsx +91 -0
- package/src/components/dashboard/__tests__/project-section.test.tsx +151 -0
- package/src/components/dashboard/__tests__/run-card.test.tsx +164 -0
- package/src/components/dashboard/__tests__/run-filter-bar.test.tsx +109 -0
- package/src/components/dashboard/__tests__/run-list.test.tsx +123 -0
- package/src/components/dashboard/__tests__/search-filter.test.tsx +150 -0
- package/src/components/dashboard/__tests__/virtualized-run-list.test.tsx +179 -0
- package/src/components/dashboard/breakpoint-banner.tsx +301 -0
- package/src/components/dashboard/catch-up-banner.tsx +88 -0
- package/src/components/dashboard/executive-summary-banner.tsx +174 -0
- package/src/components/dashboard/global-search.tsx +323 -0
- package/src/components/dashboard/kpi-grid.tsx +140 -0
- package/src/components/dashboard/pagination-controls.tsx +100 -0
- package/src/components/dashboard/project-accordion.tsx +72 -0
- package/src/components/dashboard/project-health-card.tsx +536 -0
- package/src/components/dashboard/project-list-view.tsx +246 -0
- package/src/components/dashboard/project-search-input.tsx +41 -0
- package/src/components/dashboard/project-section-header.tsx +73 -0
- package/src/components/dashboard/project-section.tsx +89 -0
- package/src/components/dashboard/run-card.tsx +218 -0
- package/src/components/dashboard/run-filter-bar.tsx +100 -0
- package/src/components/dashboard/run-list.tsx +77 -0
- package/src/components/dashboard/search-filter.tsx +69 -0
- package/src/components/dashboard/virtualized-run-list.tsx +130 -0
- package/src/components/details/.gitkeep +0 -0
- package/src/components/details/__tests__/agent-panel.test.tsx +236 -0
- package/src/components/details/__tests__/json-tree.test.tsx +347 -0
- package/src/components/details/__tests__/log-viewer.test.tsx +168 -0
- package/src/components/details/__tests__/task-detail.test.tsx +212 -0
- package/src/components/details/__tests__/timing-panel.test.tsx +271 -0
- package/src/components/details/agent-panel.tsx +234 -0
- package/src/components/details/json-tree/categorize.ts +131 -0
- package/src/components/details/json-tree/index.tsx +120 -0
- package/src/components/details/json-tree/json-node.tsx +223 -0
- package/src/components/details/json-tree/smart-summary.tsx +596 -0
- package/src/components/details/json-tree/tree-controls.tsx +47 -0
- package/src/components/details/json-tree.tsx +9 -0
- package/src/components/details/log-viewer.tsx +140 -0
- package/src/components/details/task-detail.tsx +114 -0
- package/src/components/details/timing-panel.tsx +247 -0
- package/src/components/events/.gitkeep +0 -0
- package/src/components/events/__tests__/event-item.test.tsx +211 -0
- package/src/components/events/__tests__/event-stream.test.tsx +225 -0
- package/src/components/events/event-item.tsx +121 -0
- package/src/components/events/event-stream.tsx +260 -0
- package/src/components/notifications/.gitkeep +0 -0
- package/src/components/notifications/__tests__/notification-panel.test.tsx +287 -0
- package/src/components/notifications/__tests__/notification-provider.test.tsx +585 -0
- package/src/components/notifications/__tests__/toast-stack.test.tsx +217 -0
- package/src/components/notifications/notification-panel.tsx +124 -0
- package/src/components/notifications/notification-provider.tsx +175 -0
- package/src/components/notifications/toast-stack.tsx +75 -0
- package/src/components/pipeline/.gitkeep +0 -0
- package/src/components/pipeline/__tests__/parallel-group.test.tsx +88 -0
- package/src/components/pipeline/__tests__/pipeline-view.test.tsx +345 -0
- package/src/components/pipeline/__tests__/step-card.test.tsx +330 -0
- package/src/components/pipeline/parallel-group.tsx +39 -0
- package/src/components/pipeline/pipeline-view.tsx +197 -0
- package/src/components/pipeline/step-card.tsx +166 -0
- package/src/components/providers/event-stream-provider.tsx +29 -0
- package/src/components/providers.tsx +24 -0
- package/src/components/shared/.gitkeep +0 -0
- package/src/components/shared/__tests__/empty-state.test.tsx +49 -0
- package/src/components/shared/__tests__/friendly-id.test.tsx +47 -0
- package/src/components/shared/__tests__/kbd.test.tsx +45 -0
- package/src/components/shared/__tests__/kind-badge.test.tsx +71 -0
- package/src/components/shared/__tests__/metrics-row.test.tsx +74 -0
- package/src/components/shared/__tests__/outcome-banner.test.tsx +71 -0
- package/src/components/shared/__tests__/progress-bar.test.tsx +89 -0
- package/src/components/shared/__tests__/session-pill.test.tsx +62 -0
- package/src/components/shared/__tests__/settings-modal.test.tsx +201 -0
- package/src/components/shared/__tests__/shortcuts-help.test.tsx +103 -0
- package/src/components/shared/__tests__/status-badge.test.tsx +98 -0
- package/src/components/shared/__tests__/theme-provider.test.tsx +100 -0
- package/src/components/shared/__tests__/truncated-id.test.tsx +53 -0
- package/src/components/shared/app-footer.tsx +80 -0
- package/src/components/shared/app-header.tsx +160 -0
- package/src/components/shared/empty-state.tsx +18 -0
- package/src/components/shared/error-boundary.tsx +81 -0
- package/src/components/shared/friendly-id.tsx +48 -0
- package/src/components/shared/kbd.tsx +15 -0
- package/src/components/shared/kind-badge.tsx +51 -0
- package/src/components/shared/metrics-row.tsx +106 -0
- package/src/components/shared/outcome-banner.tsx +56 -0
- package/src/components/shared/progress-bar.tsx +42 -0
- package/src/components/shared/session-pill.tsx +69 -0
- package/src/components/shared/settings-modal.tsx +509 -0
- package/src/components/shared/shortcuts-help.tsx +113 -0
- package/src/components/shared/status-badge.tsx +110 -0
- package/src/components/shared/theme-provider.tsx +46 -0
- package/src/components/shared/truncated-id.tsx +51 -0
- package/src/components/ui/.gitkeep +0 -0
- package/src/components/ui/__tests__/accordion.test.tsx +96 -0
- package/src/components/ui/__tests__/badge.test.tsx +69 -0
- package/src/components/ui/__tests__/button.test.tsx +113 -0
- package/src/components/ui/__tests__/tabs.test.tsx +75 -0
- package/src/components/ui/__tests__/tooltip.test.tsx +90 -0
- package/src/components/ui/accordion.tsx +61 -0
- package/src/components/ui/badge.tsx +25 -0
- package/src/components/ui/button.tsx +40 -0
- package/src/components/ui/card.tsx +21 -0
- package/src/components/ui/scroll-area.tsx +35 -0
- package/src/components/ui/separator.tsx +24 -0
- package/src/components/ui/tabs.tsx +64 -0
- package/src/components/ui/tooltip.tsx +37 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/hooks/__tests__/use-animated-number.test.ts +184 -0
- package/src/hooks/__tests__/use-batched-updates.test.ts +315 -0
- package/src/hooks/__tests__/use-event-stream.test.ts +243 -0
- package/src/hooks/__tests__/use-keyboard.test.ts +217 -0
- package/src/hooks/__tests__/use-notifications.test.ts +230 -0
- package/src/hooks/__tests__/use-polling.test.ts +274 -0
- package/src/hooks/__tests__/use-project-runs.test.ts +163 -0
- package/src/hooks/__tests__/use-projects.test.ts +248 -0
- package/src/hooks/__tests__/use-run-dashboard.test.ts +168 -0
- package/src/hooks/__tests__/use-run-detail.test.ts +273 -0
- package/src/hooks/__tests__/use-smart-polling.test.ts +305 -0
- package/src/hooks/use-animated-number.ts +87 -0
- package/src/hooks/use-batched-updates.ts +150 -0
- package/src/hooks/use-event-stream.ts +150 -0
- package/src/hooks/use-keyboard.ts +45 -0
- package/src/hooks/use-notifications.ts +82 -0
- package/src/hooks/use-persisted-state.ts +60 -0
- package/src/hooks/use-polling.ts +60 -0
- package/src/hooks/use-project-runs.ts +51 -0
- package/src/hooks/use-projects.ts +26 -0
- package/src/hooks/use-run-dashboard.ts +207 -0
- package/src/hooks/use-run-detail.ts +77 -0
- package/src/hooks/use-smart-polling.ts +144 -0
- package/src/lib/.gitkeep +0 -0
- package/src/lib/__tests__/cn.test.ts +69 -0
- package/src/lib/__tests__/config-loader.test.ts +210 -0
- package/src/lib/__tests__/config.test.ts +561 -0
- package/src/lib/__tests__/error-handler.test.ts +143 -0
- package/src/lib/__tests__/fetcher.test.ts +517 -0
- package/src/lib/__tests__/global-registry.test.ts +214 -0
- package/src/lib/__tests__/parser.test.ts +1532 -0
- package/src/lib/__tests__/path-resolver.test.ts +112 -0
- package/src/lib/__tests__/run-cache.test.ts +591 -0
- package/src/lib/__tests__/server-init.test.ts +512 -0
- package/src/lib/__tests__/source-discovery.test.ts +246 -0
- package/src/lib/__tests__/utils.test.ts +160 -0
- package/src/lib/__tests__/watcher.test.ts +227 -0
- package/src/lib/cn.ts +6 -0
- package/src/lib/config-loader.ts +195 -0
- package/src/lib/config.ts +20 -0
- package/src/lib/error-handler.ts +76 -0
- package/src/lib/fetcher.ts +394 -0
- package/src/lib/global-registry.ts +117 -0
- package/src/lib/parser.ts +794 -0
- package/src/lib/path-resolver.ts +16 -0
- package/src/lib/run-cache.ts +404 -0
- package/src/lib/server-init.ts +226 -0
- package/src/lib/services/__tests__/run-query-service.test.ts +819 -0
- package/src/lib/services/run-query-service.ts +286 -0
- package/src/lib/source-discovery.ts +216 -0
- package/src/lib/utils.ts +103 -0
- package/src/lib/watcher.ts +265 -0
- package/src/test/fixtures.ts +269 -0
- package/src/test/mocks/handlers.ts +110 -0
- package/src/test/mocks/server.ts +17 -0
- package/src/test/setup.ts +200 -0
- package/src/test/test-utils.tsx +36 -0
- package/src/types/.gitkeep +0 -0
- package/src/types/breakpoint.ts +17 -0
- package/src/types/index.ts +214 -0
- package/tsconfig.json +50 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module.exports=[24e3,e=>{"use strict";var t=e.i(47909),r=e.i(74017),n=e.i(96250),a=e.i(59756),o=e.i(61916),i=e.i(74677),s=e.i(69741),l=e.i(16795),u=e.i(87718),d=e.i(95169),c=e.i(47587),p=e.i(66012),h=e.i(70101),v=e.i(26937),R=e.i(10372),w=e.i(93695);e.i(52474);var f=e.i(220),g=e.i(14747),m=e.i(63372);async function E(){try{await (0,m.ensureInitialized)();let e=null,t=new ReadableStream({start(t){let r=new TextEncoder;t.enqueue(r.encode(`data: ${JSON.stringify({type:"connected",timestamp:new Date().toISOString()})}
|
|
2
|
+
|
|
3
|
+
`));let n=e=>{try{let n={type:"update",runIds:e.runIds,runId:e.runIds[0],timestamp:new Date().toISOString()};t.enqueue(r.encode(`data: ${JSON.stringify(n)}
|
|
4
|
+
|
|
5
|
+
`))}catch(e){console.error("Failed to send run-changed event:",e)}},a=e=>{try{var n;let a=(n=e.runDir,g.default.basename(n)),o={type:"new-run",runId:a,runDir:e.runDir,timestamp:new Date().toISOString()};t.enqueue(r.encode(`data: ${JSON.stringify(o)}
|
|
6
|
+
|
|
7
|
+
`))}catch(e){console.error("Failed to send new-run event:",e)}},o=e=>{console.warn("Watcher error (suppressed from SSE):",e.error?.message??"unknown",e.runDir)};m.serverEvents.on("run-changed",n),m.serverEvents.on("new-run",a),m.serverEvents.on("watcher-error",o);let i=setInterval(()=>{try{t.enqueue(r.encode(": ping\n\n"))}catch(e){console.error("Failed to send ping:",e),clearInterval(i)}},15e3);e=()=>{clearInterval(i),m.serverEvents.off("run-changed",n),m.serverEvents.off("new-run",a),m.serverEvents.off("watcher-error",o)}},cancel(){e&&(e(),e=null)}});return new Response(t,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-store",Connection:"keep-alive"}})}catch(e){return console.error("Failed to initialize SSE stream:",e),new Response(JSON.stringify({error:"Failed to initialize stream"}),{status:500,headers:{"Content-Type":"application/json"}})}}e.s(["GET",0,E,"dynamic",0,"force-dynamic"],16977);var y=e.i(16977);let C=new t.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/stream/route",pathname:"/api/stream",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/packages/observer-dashboard/src/app/api/stream/route.ts",nextConfigOutput:"",userland:y,...{}}),{workAsyncStorage:S,workUnitAsyncStorage:x,serverHooks:A}=C;async function N(e,t,n){n.requestMeta&&(0,a.setRequestMeta)(e,n.requestMeta),C.isDev&&(0,a.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let g="/api/stream/route";g=g.replace(/\/index$/,"")||"/";let m=await C.prepare(e,t,{srcPage:g,multiZoneDraftMode:!1});if(!m)return t.statusCode=400,t.end("Bad Request"),null==n.waitUntil||n.waitUntil.call(n,Promise.resolve()),null;let{buildId:E,params:y,nextConfig:S,parsedUrl:x,isDraftMode:A,prerenderManifest:N,routerServerContext:T,isOnDemandRevalidate:O,revalidateOnlyGenerated:b,resolvedPathname:I,clientReferenceManifest:P,serverActionsManifest:q}=m,_=(0,s.normalizeAppPath)(g),D=!!(N.dynamicRoutes[_]||N.routes[I]),H=async()=>((null==T?void 0:T.render404)?await T.render404(e,t,x,!1):t.end("This page could not be found"),null);if(D&&!A){let e=!!N.routes[I],t=N.dynamicRoutes[_];if(t&&!1===t.fallback&&!e){if(S.adapterPath)return await H();throw new w.NoFallbackError}}let k=null;!D||C.isDev||A||(k="/index"===(k=I)?"/":k);let U=!0===C.isDev||!D,M=D&&!U;q&&P&&(0,i.setManifestsSingleton)({page:g,clientReferenceManifest:P,serverActionsManifest:q});let F=e.method||"GET",$=(0,o.getTracer)(),j=$.getActiveScopeSpan(),K=!!(null==T?void 0:T.isWrappedByNextServer),B=!!(0,a.getRequestMeta)(e,"minimalMode"),L=(0,a.getRequestMeta)(e,"incrementalCache")||await C.getIncrementalCache(e,S,N,B);null==L||L.resetRequestCache(),globalThis.__incrementalCache=L;let z={params:y,previewProps:N.preview,renderOpts:{experimental:{authInterrupts:!!S.experimental.authInterrupts},cacheComponents:!!S.cacheComponents,supportsDynamicResponse:U,incrementalCache:L,cacheLifeProfiles:S.cacheLife,waitUntil:n.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,r,n,a)=>C.onRequestError(e,t,n,a,T)},sharedContext:{buildId:E}},G=new l.NodeNextRequest(e),J=new l.NodeNextResponse(t),W=u.NextRequestAdapter.fromNodeNextRequest(G,(0,u.signalFromNodeResponse)(t));try{let a,i=async e=>C.handle(W,z).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let r=$.getRootSpanAttributes();if(!r)return;if(r.get("next.span_type")!==d.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${r.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let n=r.get("next.route");if(n){let t=`${F} ${n}`;e.setAttributes({"next.route":n,"http.route":n,"next.span_name":t}),e.updateName(t),a&&a!==e&&(a.setAttribute("http.route",n),a.updateName(t))}else e.updateName(`${F} ${g}`)}),s=async a=>{var o,s;let l=async({previousCacheEntry:r})=>{try{if(!B&&O&&b&&!r)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let o=await i(a);e.fetchMetrics=z.renderOpts.fetchMetrics;let s=z.renderOpts.pendingWaitUntil;s&&n.waitUntil&&(n.waitUntil(s),s=void 0);let l=z.renderOpts.collectedTags;if(!D)return await (0,p.sendResponse)(G,J,o,z.renderOpts.pendingWaitUntil),null;{let e=await o.blob(),t=(0,h.toNodeOutgoingHttpHeaders)(o.headers);l&&(t[R.NEXT_CACHE_TAGS_HEADER]=l),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let r=void 0!==z.renderOpts.collectedRevalidate&&!(z.renderOpts.collectedRevalidate>=R.INFINITE_CACHE)&&z.renderOpts.collectedRevalidate,n=void 0===z.renderOpts.collectedExpire||z.renderOpts.collectedExpire>=R.INFINITE_CACHE?void 0:z.renderOpts.collectedExpire;return{value:{kind:f.CachedRouteKind.APP_ROUTE,status:o.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:r,expire:n}}}}catch(t){throw(null==r?void 0:r.isStale)&&await C.onRequestError(e,t,{routerKind:"App Router",routePath:g,routeType:"route",revalidateReason:(0,c.getRevalidateReason)({isStaticGeneration:M,isOnDemandRevalidate:O})},!1,T),t}},u=await C.handleResponse({req:e,nextConfig:S,cacheKey:k,routeKind:r.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:N,isRoutePPREnabled:!1,isOnDemandRevalidate:O,revalidateOnlyGenerated:b,responseGenerator:l,waitUntil:n.waitUntil,isMinimalMode:B});if(!D)return null;if((null==u||null==(o=u.value)?void 0:o.kind)!==f.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==u||null==(s=u.value)?void 0:s.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});B||t.setHeader("x-nextjs-cache",O?"REVALIDATED":u.isMiss?"MISS":u.isStale?"STALE":"HIT"),A&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let d=(0,h.fromNodeOutgoingHttpHeaders)(u.value.headers);return B&&D||d.delete(R.NEXT_CACHE_TAGS_HEADER),!u.cacheControl||t.getHeader("Cache-Control")||d.get("Cache-Control")||d.set("Cache-Control",(0,v.getCacheControlHeader)(u.cacheControl)),await (0,p.sendResponse)(G,J,new Response(u.value.body,{headers:d,status:u.value.status||200})),null};K&&j?await s(j):(a=$.getActiveScopeSpan(),await $.withPropagatedContext(e.headers,()=>$.trace(d.BaseServerSpan.handleRequest,{spanName:`${F} ${g}`,kind:o.SpanKind.SERVER,attributes:{"http.method":F,"http.target":e.url}},s),void 0,!K))}catch(t){if(t instanceof w.NoFallbackError||await C.onRequestError(e,t,{routerKind:"App Router",routePath:_,routeType:"route",revalidateReason:(0,c.getRevalidateReason)({isStaticGeneration:M,isOnDemandRevalidate:O})},!1,T),D)throw t;return await (0,p.sendResponse)(G,J,new Response(null,{status:500})),null}}e.s(["handler",0,N,"patchFetch",0,function(){return(0,n.patchFetch)({workAsyncStorage:S,workUnitAsyncStorage:x})},"routeModule",0,C,"serverHooks",0,A,"workAsyncStorage",0,S,"workUnitAsyncStorage",0,x],24e3)}];
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js.map
|
package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0nyyph-.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/observer-dashboard/src/app/api/stream/route.ts","../../../../../node_modules/next/dist/esm/build/templates/app-route.js"],"sourcesContent":["import path from \"path\";\nimport { ensureInitialized, serverEvents, type BatchedRunChangedEvent } from \"@/lib/server-init\";\n\nexport const dynamic = \"force-dynamic\";\n\n// Extract runId from a runDir path (last segment of the directory)\nfunction extractRunId(runDir: string): string {\n return path.basename(runDir);\n}\n\nexport async function GET() {\n try {\n // Ensure watcher and cache are initialized\n await ensureInitialized();\n\n // Track cleanup via closure so cancel() can access it\n let cleanup: (() => void) | null = null;\n\n const stream = new ReadableStream({\n start(controller) {\n const encoder = new TextEncoder();\n\n // Send initial connection message\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"connected\", timestamp: new Date().toISOString() })}\\n\\n`\n )\n );\n\n // Listen for run-changed events (batched by leading-edge debounce).\n // Each event contains runIds[] and runDirs[] for targeted client refresh.\n const runChangedListener = (event: BatchedRunChangedEvent) => {\n try {\n const message = {\n type: \"update\",\n runIds: event.runIds,\n // Keep singular runId for backward compatibility (first in batch)\n runId: event.runIds[0],\n timestamp: new Date().toISOString(),\n };\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(message)}\\n\\n`)\n );\n } catch (err) {\n console.error(\"Failed to send run-changed event:\", err);\n }\n };\n\n // Listen for new-run events\n const newRunListener = (event: {\n type: string;\n runDir: string;\n error?: Error;\n }) => {\n try {\n const runId = extractRunId(event.runDir);\n const message = {\n type: \"new-run\",\n runId,\n runDir: event.runDir,\n timestamp: new Date().toISOString(),\n };\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(message)}\\n\\n`)\n );\n } catch (err) {\n console.error(\"Failed to send new-run event:\", err);\n }\n };\n\n // Listen for watcher-error events (deduplicated in server-init)\n // These are logged server-side but NOT forwarded as SSE data events\n // to prevent transient filesystem errors from triggering client-side\n // status flashes. The client will self-heal via normal polling.\n const errorListener = (event: {\n type: string;\n runDir: string;\n error?: Error;\n }) => {\n // Log server-side only; do not push to client SSE stream\n console.warn(\n \"Watcher error (suppressed from SSE):\",\n event.error?.message ?? \"unknown\",\n event.runDir\n );\n };\n\n serverEvents.on(\"run-changed\", runChangedListener);\n serverEvents.on(\"new-run\", newRunListener);\n serverEvents.on(\"watcher-error\", errorListener);\n\n // Keep-alive ping every 15 seconds\n const pingInterval = setInterval(() => {\n try {\n controller.enqueue(encoder.encode(\": ping\\n\\n\"));\n } catch (err) {\n console.error(\"Failed to send ping:\", err);\n clearInterval(pingInterval);\n }\n }, 15000);\n\n // Store cleanup via closure (accessible from cancel)\n cleanup = () => {\n clearInterval(pingInterval);\n serverEvents.off(\"run-changed\", runChangedListener);\n serverEvents.off(\"new-run\", newRunListener);\n serverEvents.off(\"watcher-error\", errorListener);\n };\n },\n cancel() {\n if (cleanup) {\n cleanup();\n cleanup = null;\n }\n },\n });\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-store\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n console.error(\"Failed to initialize SSE stream:\", error);\n return new Response(\n JSON.stringify({ error: \"Failed to initialize stream\" }),\n {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n }\n );\n }\n}\n\n","import { AppRouteRouteModule } from \"next/dist/esm/server/route-modules/app-route/module.compiled\";\nimport { RouteKind } from \"next/dist/esm/server/route-kind\";\nimport { patchFetch as _patchFetch } from \"next/dist/esm/server/lib/patch-fetch\";\nimport { addRequestMeta, getRequestMeta, setRequestMeta } from \"next/dist/esm/server/request-meta\";\nimport { getTracer, SpanKind } from \"next/dist/esm/server/lib/trace/tracer\";\nimport { setManifestsSingleton } from \"next/dist/esm/server/app-render/manifests-singleton\";\nimport { normalizeAppPath } from \"next/dist/esm/shared/lib/router/utils/app-paths\";\nimport { NodeNextRequest, NodeNextResponse } from \"next/dist/esm/server/base-http/node\";\nimport { NextRequestAdapter, signalFromNodeResponse } from \"next/dist/esm/server/web/spec-extension/adapters/next-request\";\nimport { BaseServerSpan } from \"next/dist/esm/server/lib/trace/constants\";\nimport { getRevalidateReason } from \"next/dist/esm/server/instrumentation/utils\";\nimport { sendResponse } from \"next/dist/esm/server/send-response\";\nimport { fromNodeOutgoingHttpHeaders, toNodeOutgoingHttpHeaders } from \"next/dist/esm/server/web/utils\";\nimport { getCacheControlHeader } from \"next/dist/esm/server/lib/cache-control\";\nimport { INFINITE_CACHE, NEXT_CACHE_TAGS_HEADER } from \"next/dist/esm/lib/constants\";\nimport { NoFallbackError } from \"next/dist/esm/shared/lib/no-fallback-error.external\";\nimport { CachedRouteKind } from \"next/dist/esm/server/response-cache\";\nimport * as userland from \"INNER_APP_ROUTE\";\n// We inject the nextConfigOutput here so that we can use them in the route\n// module.\nconst nextConfigOutput = \"\"\nconst routeModule = new AppRouteRouteModule({\n definition: {\n kind: RouteKind.APP_ROUTE,\n page: \"/api/stream/route\",\n pathname: \"/api/stream\",\n filename: \"route\",\n bundlePath: \"\"\n },\n distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '',\n relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '',\n resolvedPagePath: \"[project]/packages/observer-dashboard/src/app/api/stream/route.ts\",\n nextConfigOutput,\n // The static import is used for initialization (methods, dynamic, etc.).\n userland: userland,\n // In Turbopack dev mode, also provide a getter that calls require() on every\n // request. This re-reads from devModuleCache so HMR updates are picked up,\n // and the async wrapper unwraps async-module Promises (ESM-only\n // serverExternalPackages) automatically.\n ...process.env.TURBOPACK && process.env.__NEXT_DEV_SERVER ? {\n getUserland: ()=>import(\"INNER_APP_ROUTE\")\n } : {}\n});\n// Pull out the exports that we need to expose from the module. This should\n// be eliminated when we've moved the other routes to the new format. These\n// are used to hook into the route.\nconst { workAsyncStorage, workUnitAsyncStorage, serverHooks } = routeModule;\nfunction patchFetch() {\n return _patchFetch({\n workAsyncStorage,\n workUnitAsyncStorage\n });\n}\nexport { routeModule, workAsyncStorage, workUnitAsyncStorage, serverHooks, patchFetch, };\nexport async function handler(req, res, ctx) {\n if (ctx.requestMeta) {\n setRequestMeta(req, ctx.requestMeta);\n }\n if (routeModule.isDev) {\n addRequestMeta(req, 'devRequestTimingInternalsEnd', process.hrtime.bigint());\n }\n let srcPage = \"/api/stream/route\";\n // turbopack doesn't normalize `/index` in the page name\n // so we need to to process dynamic routes properly\n // TODO: fix turbopack providing differing value from webpack\n if (process.env.TURBOPACK) {\n srcPage = srcPage.replace(/\\/index$/, '') || '/';\n } else if (srcPage === '/index') {\n // we always normalize /index specifically\n srcPage = '/';\n }\n const multiZoneDraftMode = process.env.__NEXT_MULTI_ZONE_DRAFT_MODE;\n const prepareResult = await routeModule.prepare(req, res, {\n srcPage,\n multiZoneDraftMode\n });\n if (!prepareResult) {\n res.statusCode = 400;\n res.end('Bad Request');\n ctx.waitUntil == null ? void 0 : ctx.waitUntil.call(ctx, Promise.resolve());\n return null;\n }\n const { buildId, params, nextConfig, parsedUrl, isDraftMode, prerenderManifest, routerServerContext, isOnDemandRevalidate, revalidateOnlyGenerated, resolvedPathname, clientReferenceManifest, serverActionsManifest } = prepareResult;\n const normalizedSrcPage = normalizeAppPath(srcPage);\n let isIsr = Boolean(prerenderManifest.dynamicRoutes[normalizedSrcPage] || prerenderManifest.routes[resolvedPathname]);\n const render404 = async ()=>{\n // TODO: should route-module itself handle rendering the 404\n if (routerServerContext == null ? void 0 : routerServerContext.render404) {\n await routerServerContext.render404(req, res, parsedUrl, false);\n } else {\n res.end('This page could not be found');\n }\n return null;\n };\n if (isIsr && !isDraftMode) {\n const isPrerendered = Boolean(prerenderManifest.routes[resolvedPathname]);\n const prerenderInfo = prerenderManifest.dynamicRoutes[normalizedSrcPage];\n if (prerenderInfo) {\n if (prerenderInfo.fallback === false && !isPrerendered) {\n if (nextConfig.adapterPath) {\n return await render404();\n }\n throw new NoFallbackError();\n }\n }\n }\n let cacheKey = null;\n if (isIsr && !routeModule.isDev && !isDraftMode) {\n cacheKey = resolvedPathname;\n // ensure /index and / is normalized to one key\n cacheKey = cacheKey === '/index' ? '/' : cacheKey;\n }\n const supportsDynamicResponse = // If we're in development, we always support dynamic HTML\n routeModule.isDev === true || // If this is not SSG or does not have static paths, then it supports\n // dynamic HTML.\n !isIsr;\n // This is a revalidation request if the request is for a static\n // page and it is not being resumed from a postponed render and\n // it is not a dynamic RSC request then it is a revalidation\n // request.\n const isStaticGeneration = isIsr && !supportsDynamicResponse;\n // Before rendering (which initializes component tree modules), we have to\n // set the reference manifests to our global store so Server Action's\n // encryption util can access to them at the top level of the page module.\n if (serverActionsManifest && clientReferenceManifest) {\n setManifestsSingleton({\n page: srcPage,\n clientReferenceManifest,\n serverActionsManifest\n });\n }\n const method = req.method || 'GET';\n const tracer = getTracer();\n const activeSpan = tracer.getActiveScopeSpan();\n const isWrappedByNextServer = Boolean(routerServerContext == null ? void 0 : routerServerContext.isWrappedByNextServer);\n const isMinimalMode = Boolean(getRequestMeta(req, 'minimalMode'));\n const incrementalCache = getRequestMeta(req, 'incrementalCache') || await routeModule.getIncrementalCache(req, nextConfig, prerenderManifest, isMinimalMode);\n incrementalCache == null ? void 0 : incrementalCache.resetRequestCache();\n globalThis.__incrementalCache = incrementalCache;\n const context = {\n params,\n previewProps: prerenderManifest.preview,\n renderOpts: {\n experimental: {\n authInterrupts: Boolean(nextConfig.experimental.authInterrupts)\n },\n cacheComponents: Boolean(nextConfig.cacheComponents),\n supportsDynamicResponse,\n incrementalCache,\n cacheLifeProfiles: nextConfig.cacheLife,\n waitUntil: ctx.waitUntil,\n onClose: (cb)=>{\n res.on('close', cb);\n },\n onAfterTaskError: undefined,\n onInstrumentationRequestError: (error, _request, errorContext, silenceLog)=>routeModule.onRequestError(req, error, errorContext, silenceLog, routerServerContext)\n },\n sharedContext: {\n buildId\n }\n };\n const nodeNextReq = new NodeNextRequest(req);\n const nodeNextRes = new NodeNextResponse(res);\n const nextReq = NextRequestAdapter.fromNodeNextRequest(nodeNextReq, signalFromNodeResponse(res));\n try {\n let parentSpan;\n const invokeRouteModule = async (span)=>{\n return routeModule.handle(nextReq, context).finally(()=>{\n if (!span) return;\n span.setAttributes({\n 'http.status_code': res.statusCode,\n 'next.rsc': false\n });\n const rootSpanAttributes = tracer.getRootSpanAttributes();\n // We were unable to get attributes, probably OTEL is not enabled\n if (!rootSpanAttributes) {\n return;\n }\n if (rootSpanAttributes.get('next.span_type') !== BaseServerSpan.handleRequest) {\n console.warn(`Unexpected root span type '${rootSpanAttributes.get('next.span_type')}'. Please report this Next.js issue https://github.com/vercel/next.js`);\n return;\n }\n const route = rootSpanAttributes.get('next.route');\n if (route) {\n const name = `${method} ${route}`;\n span.setAttributes({\n 'next.route': route,\n 'http.route': route,\n 'next.span_name': name\n });\n span.updateName(name);\n // Propagate http.route to the parent span if one exists (e.g.\n // a platform-created HTTP span in adapter deployments).\n if (parentSpan && parentSpan !== span) {\n parentSpan.setAttribute('http.route', route);\n parentSpan.updateName(name);\n }\n } else {\n span.updateName(`${method} ${srcPage}`);\n }\n });\n };\n const handleResponse = async (currentSpan)=>{\n var _cacheEntry_value;\n const responseGenerator = async ({ previousCacheEntry })=>{\n try {\n if (!isMinimalMode && isOnDemandRevalidate && revalidateOnlyGenerated && !previousCacheEntry) {\n res.statusCode = 404;\n // on-demand revalidate always sets this header\n res.setHeader('x-nextjs-cache', 'REVALIDATED');\n res.end('This page could not be found');\n return null;\n }\n const response = await invokeRouteModule(currentSpan);\n req.fetchMetrics = context.renderOpts.fetchMetrics;\n let pendingWaitUntil = context.renderOpts.pendingWaitUntil;\n // Attempt using provided waitUntil if available\n // if it's not we fallback to sendResponse's handling\n if (pendingWaitUntil) {\n if (ctx.waitUntil) {\n ctx.waitUntil(pendingWaitUntil);\n pendingWaitUntil = undefined;\n }\n }\n const cacheTags = context.renderOpts.collectedTags;\n // If the request is for a static response, we can cache it so long\n // as it's not edge.\n if (isIsr) {\n const blob = await response.blob();\n // Copy the headers from the response.\n const headers = toNodeOutgoingHttpHeaders(response.headers);\n if (cacheTags) {\n headers[NEXT_CACHE_TAGS_HEADER] = cacheTags;\n }\n if (!headers['content-type'] && blob.type) {\n headers['content-type'] = blob.type;\n }\n const revalidate = typeof context.renderOpts.collectedRevalidate === 'undefined' || context.renderOpts.collectedRevalidate >= INFINITE_CACHE ? false : context.renderOpts.collectedRevalidate;\n const expire = typeof context.renderOpts.collectedExpire === 'undefined' || context.renderOpts.collectedExpire >= INFINITE_CACHE ? undefined : context.renderOpts.collectedExpire;\n // Create the cache entry for the response.\n const cacheEntry = {\n value: {\n kind: CachedRouteKind.APP_ROUTE,\n status: response.status,\n body: Buffer.from(await blob.arrayBuffer()),\n headers\n },\n cacheControl: {\n revalidate,\n expire\n }\n };\n return cacheEntry;\n } else {\n // send response without caching if not ISR\n await sendResponse(nodeNextReq, nodeNextRes, response, context.renderOpts.pendingWaitUntil);\n return null;\n }\n } catch (err) {\n // if this is a background revalidate we need to report\n // the request error here as it won't be bubbled\n if (previousCacheEntry == null ? void 0 : previousCacheEntry.isStale) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: srcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n throw err;\n }\n };\n const cacheEntry = await routeModule.handleResponse({\n req,\n nextConfig,\n cacheKey,\n routeKind: RouteKind.APP_ROUTE,\n isFallback: false,\n prerenderManifest,\n isRoutePPREnabled: false,\n isOnDemandRevalidate,\n revalidateOnlyGenerated,\n responseGenerator,\n waitUntil: ctx.waitUntil,\n isMinimalMode\n });\n // we don't create a cacheEntry for ISR\n if (!isIsr) {\n return null;\n }\n if ((cacheEntry == null ? void 0 : (_cacheEntry_value = cacheEntry.value) == null ? void 0 : _cacheEntry_value.kind) !== CachedRouteKind.APP_ROUTE) {\n var _cacheEntry_value1;\n throw Object.defineProperty(new Error(`Invariant: app-route received invalid cache entry ${cacheEntry == null ? void 0 : (_cacheEntry_value1 = cacheEntry.value) == null ? void 0 : _cacheEntry_value1.kind}`), \"__NEXT_ERROR_CODE\", {\n value: \"E701\",\n enumerable: false,\n configurable: true\n });\n }\n if (!isMinimalMode) {\n res.setHeader('x-nextjs-cache', isOnDemandRevalidate ? 'REVALIDATED' : cacheEntry.isMiss ? 'MISS' : cacheEntry.isStale ? 'STALE' : 'HIT');\n }\n // Draft mode should never be cached\n if (isDraftMode) {\n res.setHeader('Cache-Control', 'private, no-cache, no-store, max-age=0, must-revalidate');\n }\n const headers = fromNodeOutgoingHttpHeaders(cacheEntry.value.headers);\n if (!(isMinimalMode && isIsr)) {\n headers.delete(NEXT_CACHE_TAGS_HEADER);\n }\n // If cache control is already set on the response we don't\n // override it to allow users to customize it via next.config\n if (cacheEntry.cacheControl && !res.getHeader('Cache-Control') && !headers.get('Cache-Control')) {\n headers.set('Cache-Control', getCacheControlHeader(cacheEntry.cacheControl));\n }\n await sendResponse(nodeNextReq, nodeNextRes, // @ts-expect-error - Argument of type 'Buffer<ArrayBufferLike>' is not assignable to parameter of type 'BodyInit | null | undefined'.\n new Response(cacheEntry.value.body, {\n headers,\n status: cacheEntry.value.status || 200\n }));\n return null;\n };\n // TODO: activeSpan code path is for when wrapped by\n // next-server can be removed when this is no longer used\n if (isWrappedByNextServer && activeSpan) {\n await handleResponse(activeSpan);\n } else {\n parentSpan = tracer.getActiveScopeSpan();\n await tracer.withPropagatedContext(req.headers, ()=>tracer.trace(BaseServerSpan.handleRequest, {\n spanName: `${method} ${srcPage}`,\n kind: SpanKind.SERVER,\n attributes: {\n 'http.method': method,\n 'http.target': req.url\n }\n }, handleResponse), undefined, !isWrappedByNextServer);\n }\n } catch (err) {\n if (!(err instanceof NoFallbackError)) {\n const silenceLog = false;\n await routeModule.onRequestError(req, err, {\n routerKind: 'App Router',\n routePath: normalizedSrcPage,\n routeType: 'route',\n revalidateReason: getRevalidateReason({\n isStaticGeneration,\n isOnDemandRevalidate\n })\n }, silenceLog, routerServerContext);\n }\n // rethrow so that we can handle serving error page\n // If this is during static generation, throw the error again.\n if (isIsr) throw err;\n // Otherwise, send a 500 response.\n await sendResponse(nodeNextReq, nodeNextRes, new Response(null, {\n status: 500\n }));\n return null;\n }\n}\n\n//# sourceMappingURL=app-route.js.map\n"],"names":["dynamic","extractRunId","runDir","basename","GET","cleanup","stream","ReadableStream","start","controller","encoder","TextEncoder","enqueue","encode","JSON","stringify","type","timestamp","Date","toISOString","event","runChangedListener","message","err","runIds","runId","console","error","newRunListener","off","errorListener","Connection","warn","on","pingInterval","setInterval","clearInterval","cancel","Response","headers","status"],"mappings":"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","ignoreList":[1]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports=[37315,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(46786);function a(e){if(!(e instanceof Error))return!1;let t=e.code;return"ENOENT"===t||"ENOTDIR"===t||e.message.includes("ENOENT")}let s=process.env.OBSERVER_REGISTRY||n.default.join(r.default.homedir(),".a5c","observer.json"),i=null,l=0;async function o(e){let r=n.default.dirname(s);await t.promises.mkdir(r,{recursive:!0});let i={};try{let e=await t.promises.readFile(s,"utf-8");i=JSON.parse(e)}catch(e){a(e)||console.warn(`[config] Failed to read existing config at ${s} before merge:`,e)}let l={...i,sources:e.sources,...void 0!==e.pollInterval?{pollInterval:e.pollInterval}:{},...void 0!==e.theme?{theme:e.theme}:{},...void 0!==e.staleThresholdMs?{staleThresholdMs:e.staleThresholdMs}:{},...void 0!==e.recentCompletionWindowMs?{recentCompletionWindowMs:e.recentCompletionWindowMs}:{},...void 0!==e.retentionDays?{retentionDays:e.retentionDays}:{},...void 0!==e.hiddenProjects?{hiddenProjects:e.hiddenProjects}:{}};await t.promises.writeFile(s,JSON.stringify(l,null,2)+"\n","utf-8")}async function d(){try{let e=await t.promises.readFile(s,"utf-8"),n=JSON.parse(e);return{sources:Array.isArray(n.sources)?n.sources.map(e=>({path:String(e.path||""),depth:"number"==typeof e.depth?e.depth:2,label:e.label?String(e.label):void 0})):[],pollInterval:"number"==typeof n.pollInterval?n.pollInterval:void 0,theme:"dark"===n.theme||"light"===n.theme?n.theme:void 0,staleThresholdMs:"number"==typeof n.staleThresholdMs?n.staleThresholdMs:void 0,recentCompletionWindowMs:"number"==typeof n.recentCompletionWindowMs?n.recentCompletionWindowMs:void 0,retentionDays:"number"==typeof n.retentionDays?n.retentionDays:void 0,hiddenProjects:Array.isArray(n.hiddenProjects)?n.hiddenProjects.filter(e=>"string"==typeof e):void 0}}catch(e){return a(e)||console.warn(`[config] Failed to load registry from ${s} — using defaults:`,e),{sources:[]}}}async function u(){let e=Date.now();if(i&&e-l<1e4)return i;let t=await d(),r=function(){let e=[];if(process.env.OBSERVER_WATCH_DIR&&e.push({path:process.env.OBSERVER_WATCH_DIR,depth:3,label:"cli"}),process.env.WATCH_DIR&&e.push({path:process.env.WATCH_DIR,depth:0,label:"env"}),process.env.WATCH_DIRS)for(let t of process.env.WATCH_DIRS.split(",")){let n=t.trim();n&&e.push({path:n,depth:2})}return 0===e.length&&e.push({path:n.default.resolve(process.cwd(),".."),depth:3,label:"parent"}),e}(),a=t.sources.length>0?t.sources:r,s=new Set,o=a.filter(e=>{let t=n.default.resolve(e.path);return!s.has(t)&&(s.add(t),!0)}),u=process.env.OBSERVER_POLL_INTERVAL||process.env.POLL_INTERVAL,f=process.env.OBSERVER_DEFAULT_THEME||process.env.THEME,p=process.env.OBSERVER_STALE_THRESHOLD_MS,c=process.env.OBSERVER_RECENT_WINDOW_MS,h=process.env.OBSERVER_RETENTION_DAYS;return i={sources:o,port:parseInt(process.env.OBSERVER_PORT||process.env.PORT||"4800",10),pollInterval:t.pollInterval??(u?parseInt(u,10):2e3),theme:t.theme??("dark"===f||"light"===f?f:"dark"),staleThresholdMs:t.staleThresholdMs??(p?parseInt(p,10):36e5),recentCompletionWindowMs:t.recentCompletionWindowMs??(c?parseInt(c,10):144e5),retentionDays:t.retentionDays??(h?parseInt(h,10):30),hiddenProjects:t.hiddenProjects??[]},l=e,i}e.s(["getConfig",0,u,"invalidateConfigCache",0,function(){i=null,l=0},"isNotFoundError",0,a,"writeConfig",0,o])},75619,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(37315);async function a(e){let a=[];async function s(i,l){try{if(0===e.depth)return(await t.promises.readdir(i,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>n.default.join(i,e.name));let r=n.default.join(i,".a5c","runs");try{(await t.promises.stat(r)).isDirectory()&&a.push(r)}catch{}if(l<e.depth)for(let e of(await t.promises.readdir(i,{withFileTypes:!0})))e.isDirectory()&&!e.name.startsWith(".")&&"node_modules"!==e.name&&await s(n.default.join(i,e.name),l+1)}catch(e){(0,r.isNotFoundError)(e)||console.warn(`[config] Cannot scan directory ${i} (depth=${l}):`,e)}}if(0===e.depth)try{return(await t.promises.readdir(e.path,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(t=>n.default.join(e.path,t.name))}catch(t){return console.warn(`[config] Cannot list runs in direct source ${e.path}:`,t),[]}return await s(e.path,0),a}let s=[],i=0;async function l(){let e=Date.now();if(s.length>0&&e-i<1e4)return s;let l=await (0,r.getConfig)(),o=[];for(let e of l.sources)if(0===e.depth){let a=e.label||n.default.basename(e.path);try{for(let s of(await t.promises.readdir(e.path,{withFileTypes:!0})))if(s.isDirectory()){let i=a;try{let r=n.default.join(e.path,s.name,"run.json"),a=await t.promises.readFile(r,"utf-8"),l=JSON.parse(a);l.projectName&&(i=l.projectName)}catch(t){(0,r.isNotFoundError)(t)||console.warn(`[config] Failed to read run.json in ${n.default.join(e.path,s.name)} — using fallback project name:`,t)}o.push({runDir:n.default.join(e.path,s.name),source:e,projectName:i,projectPath:e.path})}}catch(t){console.warn(`[config] Source directory not accessible ${e.path}:`,t)}}else for(let r of(await a(e))){let{projectName:a,projectPath:s}=function(e){let t=n.default.dirname(e),r=n.default.dirname(t);return{projectName:n.default.basename(r),projectPath:r}}(r);try{for(let i of(await t.promises.readdir(r,{withFileTypes:!0})))i.isDirectory()&&o.push({runDir:n.default.join(r,i.name),source:e,projectName:a,projectPath:s})}catch(e){console.warn(`[config] Cannot read runs directory ${r}:`,e)}}let d=new Map;for(let e of o){let r=n.default.basename(e.runDir);if(d.has(r)){let a=d.get(r);!await t.promises.access(n.default.join(a.runDir,"run.json")).then(()=>!0,()=>!1)&&await t.promises.access(n.default.join(e.runDir,"run.json")).then(()=>!0,()=>!1)&&d.set(r,e)}else d.set(r,e)}let u=Array.from(d.values());return s=u,i=Date.now(),u}async function o(){let e=await (0,r.getConfig)(),n=[];for(let r of e.sources)if(0===r.depth)try{await t.promises.access(r.path),n.push(r.path)}catch(e){console.warn(`[config] Watch source path not accessible ${r.path}:`,e)}else{let e=await a(r);n.push(...e)}return n}e.s(["discoverAllRunDirs",0,l,"discoverAllRunsParentDirs",0,o,"invalidateDiscoveryCache",0,function(){s=[],i=0}])},40564,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(37315);function a(e){if(!(e instanceof Error))return!1;let t=e.code;return"ENOENT"===t||"ENOTDIR"===t||e.message.includes("ENOENT")}function s(e){if(!e)return null;let t=new Date(e).getTime();return Number.isFinite(t)?t:null}function i(e,t){return null==e||null==t?null:{startMs:e,endMs:Math.max(t,e)}}function l(e){let t=i(s(e.startedAt),s(e.finishedAt));return t||i(s(e.requestedAt),s(e.resolvedAt))}function o(e){let t=l(e);if(t)return t.endMs-t.startMs}async function d(e){try{return await t.promises.access(e),!0}catch(t){return a(t)||console.warn(`[parser] Unexpected error checking existence of ${e}:`,t),!1}}async function u(e,n){try{let n=await t.promises.readFile(e,"utf-8");return JSON.parse(n)}catch(t){return a(t)||console.warn(`[parser] Failed to read/parse JSON from ${e}:`,t),n}}async function f(e){try{return await t.promises.readFile(e,"utf-8")}catch(t){a(t)||console.warn(`[parser] Failed to read text file ${e}:`,t);return}}async function p(e,t=50){let n=Array(e.length),r=0;async function a(){for(;r<e.length;){let t=r++;try{let r=await e[t]();n[t]={status:"fulfilled",value:r}}catch(e){n[t]={status:"rejected",reason:e}}}}let s=Math.min(t,e.length),i=[];for(let e=0;e<s;e++)i.push(a());return await Promise.all(i),n}function c(e,t){if(!e||!e.type)return null;let n=t.replace(/\.json$/,"").split(".");return{seq:parseInt(n[0],10)||0,id:n[1]||"",ts:e.recordedAt||e.ts||"",type:e.type,payload:e.data||e.payload||{}}}async function h(e){return(await m(e)).events}async function m(e,r,a){if(!await d(e))return{events:[],fileCount:0};let s=(await t.promises.readdir(e)).filter(e=>e.endsWith(".json")).sort(),i=s.length;if(void 0!==r&&void 0!==a&&a>=0&&i>=a){if(a>=i)return{events:r,fileCount:i};let t=s.slice(a),l=t.map(t=>()=>u(n.default.join(e,t),null)),o=await p(l),d=[];for(let e=0;e<t.length;e++){let n=o[e],r="fulfilled"===n.status?n.value:null;if(r){let n=c(r,t[e]);n&&d.push(n)}}return{events:[...r,...d].sort((e,t)=>e.seq-t.seq),fileCount:i}}let l=s.map(t=>()=>u(n.default.join(e,t),null)),o=await p(l),f=[];for(let e=0;e<s.length;e++){let t=o[e],n="fulfilled"===t.status?t.value:null;if(n){let t=c(n,s[e]);t&&f.push(t)}}return{events:f.sort((e,t)=>e.seq-t.seq),fileCount:i}}async function y(e,t){let a,s,i,d,f,c,h=await u(n.default.join(e,"run.json"),{}),y=await m(n.default.join(e,"journal"),t?.previousEvents,t?.previousFileCount),g=y.events,w=g.find(e=>"RUN_CREATED"===e.type),v=g.find(e=>"RUN_COMPLETED"===e.type),E=g.find(e=>"RUN_FAILED"===e.type),D=w?.payload||{},T=new Map,j=[];for(let e of g){if("EFFECT_REQUESTED"===e.type){let t=e.payload;j.push(t),T.set(t.effectId,{effectId:t.effectId,kind:t.kind,title:t.label||t.taskId,label:t.label||t.taskId,status:"requested",invocationKey:t.invocationKey,stepId:t.stepId,taskId:t.taskId,requestedAt:e.ts})}if("EFFECT_RESOLVED"===e.type){let t=e.payload,n=T.get(t.effectId);n&&(n.status="ok"===t.status?"resolved":"error",n.resolvedAt=e.ts,n.startedAt=t.startedAt,n.finishedAt=t.finishedAt,n.duration=o({startedAt:t.startedAt,finishedAt:t.finishedAt,requestedAt:n.requestedAt,resolvedAt:e.ts}),t.error&&(n.error={name:t.error.name,message:t.error.message,stack:t.error.stack}))}}if(j.length>0){let t=j.map(t=>()=>u(n.default.join(e,"tasks",t.effectId,"task.json"),null)),r=await p(t);for(let e=0;e<j.length;e++){let t=j[e],n=r[e],a="fulfilled"===n.status?n.value:null;if(a){let e=T.get(t.effectId);if(e.title=a.title||e.title,a.agent&&"object"==typeof a.agent){let t=a.agent;e.agent={name:t.name||"unknown",prompt:t.prompt}}if("breakpoint"===t.kind){let t=a.inputs;t&&"string"==typeof t.question&&(e.breakpointQuestion=t.question)}}}}let I=Array.from(T.values()),k=I.filter(e=>"resolved"===e.status).length,A=I.filter(e=>"error"===e.status).length,R=I.find(e=>"error"===e.status),C=R?R.title||R.label||R.stepId:void 0;if(E){let e=E.payload.error;e&&(a=e.name||"Error",s=e.message||e.stack||void 0)}if(!s){let e=[...g].reverse().find(e=>"EFFECT_RESOLVED"===e.type&&"error"===e.payload.status);if(e){let t=e.payload.error;t&&(a=a||t.name||"Error",s=t.message||t.stack||void 0)}}let b="pending";if(v?b="completed":E?b="failed":I.some(e=>"requested"===e.status)&&(b="waiting"),"waiting"===b){let e=I.find(e=>"breakpoint"===e.kind&&"requested"===e.status);e?.breakpointQuestion&&(i=e.breakpointQuestion)}if("waiting"===b){let e=I.filter(e=>"requested"===e.status),t=e[e.length-1];t&&(d="breakpoint"===t.kind?"breakpoint":"task")}let M=w?.ts||"",F=g[g.length-1],S=I.map(e=>l(e)).filter(e=>null!==e);if(S.length>0?f=function(e){if(0===e.length)return 0;let t=[...e].sort((e,t)=>e.startMs-t.startMs),n=0,r=t[0];for(let e=1;e<t.length;e++){let a=t[e];if(a.startMs<=r.endMs){r.endMs=Math.max(r.endMs,a.endMs);continue}n+=r.endMs-r.startMs,r=a}return n+(r.endMs-r.startMs)}(S):M&&(v||E)?f=new Date((v||E).ts).getTime()-new Date(M).getTime():M&&F&&(f=new Date(F.ts).getTime()-new Date(M).getTime()),"waiting"===b||"pending"===b){let e=F?.ts||M;if(e){let t=await (0,r.getConfig)();Date.now()-new Date(e).getTime()>t.staleThresholdMs&&(c=!0)}}return"pending"===b&&I.length>0&&!I.some(e=>"requested"===e.status)&&(c=!0),{runId:D.runId||n.default.basename(e),processId:D.processId||h?.processId||"unknown",status:b,createdAt:M,updatedAt:F?.ts||M,completedAt:(v||E)?.ts,tasks:I,events:g,totalTasks:I.length,completedTasks:k,failedTasks:A,duration:f,failedStep:C,failureError:a,failureMessage:s,breakpointQuestion:i,isStale:c,waitingKind:d,_journalFileCount:y.fileCount}}async function g(e,t){let r,a=n.default.join(e,"tasks",t);if(!await d(a))return null;let[s,i,l,p,c,m]=await Promise.allSettled([u(n.default.join(a,"task.json"),null),u(n.default.join(a,"input.json"),void 0),u(n.default.join(a,"result.json"),void 0),f(n.default.join(a,"stdout.log")),f(n.default.join(a,"stderr.log")),h(n.default.join(e,"journal"))]),y="fulfilled"===s.status?s.value:null,g="fulfilled"===i.status?i.value:void 0,w="fulfilled"===l.status?l.value:void 0,v="fulfilled"===p.status?p.value:void 0,E="fulfilled"===c.status?c.value:void 0,D="fulfilled"===m.status?m.value:[],T=w?.startedAt,j=w?.finishedAt,I=D.find(e=>"EFFECT_REQUESTED"===e.type&&e.payload.effectId===t),k=D.find(e=>"EFFECT_RESOLVED"===e.type&&e.payload.effectId===t),A=I?.ts||"",R=k?.ts,C=o({startedAt:T,finishedAt:j,requestedAt:A,resolvedAt:R}),b=g??y?.inputs,M=y?.kind||"agent";"breakpoint"===M&&b&&(r={question:b.question||"Approval required",title:b.title||y?.title||"Breakpoint",options:Array.isArray(b.options)?b.options:void 0,context:b.context});let F=k?.payload,S=w?"error"===w.status:F?.status==="error";return{effectId:t,kind:M,title:y?.title||t,label:y?.title||t,status:k?S?"error":"resolved":"requested",invocationKey:y?.invocationKey||"",stepId:y?.stepId||"",taskId:y?.taskId||"",requestedAt:A,resolvedAt:R,startedAt:T,finishedAt:j,duration:C,input:b,result:w??void 0,stdout:v,stderr:E,taskDef:y??void 0,breakpoint:r,breakpointQuestion:r?.question}}async function w(e){let a,s,i,l,o=n.default.join(e,"journal"),f=0,h="pending",m=0,y=0,g="",w=new Set,v=new Set,E=new Set,D=[];if(await d(o)){let e=(await t.promises.readdir(o)).filter(e=>e.endsWith(".json")).sort();f=e.length;let r=e.map(e=>()=>u(n.default.join(o,e),null)),a=await p(r);for(let t=0;t<e.length;t++){let n=a[t],r="fulfilled"===n.status?n.value:null;if(!r)continue;let s=c(r,e[t]);if(s){if(g=s.ts,"EFFECT_REQUESTED"===s.type){m++;let e=s.payload,t=e.effectId,n=e.kind||"agent";D.push({effectId:t,kind:n}),"breakpoint"===e.kind&&(w.add(t),E.add(t))}if("EFFECT_RESOLVED"===s.type){y++;let e=s.payload;v.add(e.effectId)}"RUN_COMPLETED"===s.type&&(h="completed"),"RUN_FAILED"===s.type&&(h="failed")}}"pending"===h&&m>0&&(h="waiting")}let T=0;if(w.size>0){let t=[...w].filter(e=>!v.has(e));if(t.length>0){let r=await Promise.all(t.map(t=>u(n.default.join(e,"tasks",t,"result.json"),null)));for(let e=0;e<t.length;e++)r[e]&&"ok"===r[e].status?v.add(t[e]):T++}}if("waiting"===h&&E.size>0){let t=[...E].filter(e=>!v.has(e));if(t.length>0){s=t[0];let r=t.map(t=>()=>u(n.default.join(e,"tasks",t,"task.json"),null)),i=await p(r);for(let e=0;e<t.length;e++){let n=i[e],r="fulfilled"===n.status?n.value:null;if(r){let n=r.inputs;if(n&&"string"==typeof n.question){a=n.question,s=t[e];break}}}}}if("waiting"===h){let e=D.filter(e=>!v.has(e.effectId)),t=e[e.length-1];t&&(i="breakpoint"===t.kind?"breakpoint":"task")}if(("waiting"===h||"pending"===h)&&g){let e=await (0,r.getConfig)();Date.now()-new Date(g).getTime()>e.staleThresholdMs&&(l=!0)}return"waiting"===h&&m>0&&y>=m&&(l=!0),{runId:n.default.basename(e),latestSeq:f,status:h,taskCount:m,completedTasks:y,updatedAt:g,pendingBreakpoints:T,breakpointQuestion:a,breakpointEffectId:s,isStale:l,waitingKind:i}}e.s(["getRunDigest",0,w,"parseJournalDir",0,h,"parseRunDir",0,y,"parseTaskDetail",0,g])}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=packages_observer-dashboard_src_lib_02.vvb.._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/observer-dashboard/src/lib/config-loader.ts","../../../../../packages/observer-dashboard/src/lib/source-discovery.ts","../../../../../packages/observer-dashboard/src/lib/parser.ts"],"sourcesContent":["import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\n/** Return true when err represents a \"file/directory not found\" filesystem error. */\nexport function isNotFoundError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const code = (err as NodeJS.ErrnoException).code;\n return code === \"ENOENT\" || code === \"ENOTDIR\" || err.message.includes(\"ENOENT\");\n}\n\nexport interface WatchSource {\n path: string;\n depth: number; // how many levels deep to search for .a5c/runs/\n label?: string;\n}\n\nexport interface ObserverConfig {\n sources: WatchSource[];\n port: number;\n pollInterval: number;\n theme: \"dark\" | \"light\";\n staleThresholdMs: number;\n recentCompletionWindowMs: number;\n retentionDays: number;\n hiddenProjects: string[];\n}\n\n// Default registry path\nconst REGISTRY_PATH =\n process.env.OBSERVER_REGISTRY ||\n path.join(os.homedir(), \".a5c\", \"observer.json\");\n\nlet cachedConfig: ObserverConfig | null = null;\nlet cacheTime = 0;\nconst CACHE_TTL = 10000; // 10s\n\n// Invalidate the config cache (called after POST /api/config writes new values)\nexport function invalidateConfigCache(): void {\n cachedConfig = null;\n cacheTime = 0;\n}\n\n// Write config to the registry file (~/.a5c/observer.json)\nexport async function writeConfig(data: {\n sources: WatchSource[];\n pollInterval?: number;\n theme?: string;\n staleThresholdMs?: number;\n recentCompletionWindowMs?: number;\n retentionDays?: number;\n hiddenProjects?: string[];\n}): Promise<void> {\n const dir = path.dirname(REGISTRY_PATH);\n await fs.mkdir(dir, { recursive: true });\n\n // Read existing file to preserve any extra fields\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(REGISTRY_PATH, \"utf-8\");\n existing = JSON.parse(content);\n } catch (err) {\n // Expected when writing config for the first time; warn if the file exists but is unreadable\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to read existing config at ${REGISTRY_PATH} before merge:`, err);\n }\n }\n\n const merged = {\n ...existing,\n sources: data.sources,\n ...(data.pollInterval !== undefined ? { pollInterval: data.pollInterval } : {}),\n ...(data.theme !== undefined ? { theme: data.theme } : {}),\n ...(data.staleThresholdMs !== undefined ? { staleThresholdMs: data.staleThresholdMs } : {}),\n ...(data.recentCompletionWindowMs !== undefined ? { recentCompletionWindowMs: data.recentCompletionWindowMs } : {}),\n ...(data.retentionDays !== undefined ? { retentionDays: data.retentionDays } : {}),\n ...(data.hiddenProjects !== undefined ? { hiddenProjects: data.hiddenProjects } : {}),\n };\n\n await fs.writeFile(REGISTRY_PATH, JSON.stringify(merged, null, 2) + \"\\n\", \"utf-8\");\n}\n\ninterface RegistryData {\n sources: WatchSource[];\n pollInterval?: number;\n theme?: \"dark\" | \"light\";\n staleThresholdMs?: number;\n recentCompletionWindowMs?: number;\n retentionDays?: number;\n hiddenProjects?: string[];\n}\n\nasync function loadRegistry(): Promise<RegistryData> {\n try {\n const content = await fs.readFile(REGISTRY_PATH, \"utf-8\");\n const parsed = JSON.parse(content);\n const sources = Array.isArray(parsed.sources)\n ? parsed.sources.map((s: Record<string, unknown>) => ({\n path: String(s.path || \"\"),\n depth: typeof s.depth === \"number\" ? s.depth : 2,\n label: s.label ? String(s.label) : undefined,\n }))\n : [];\n return {\n sources,\n pollInterval: typeof parsed.pollInterval === \"number\" ? parsed.pollInterval : undefined,\n theme: parsed.theme === \"dark\" || parsed.theme === \"light\" ? parsed.theme : undefined,\n staleThresholdMs: typeof parsed.staleThresholdMs === \"number\" ? parsed.staleThresholdMs : undefined,\n recentCompletionWindowMs: typeof parsed.recentCompletionWindowMs === \"number\" ? parsed.recentCompletionWindowMs : undefined,\n retentionDays: typeof parsed.retentionDays === \"number\" ? parsed.retentionDays : undefined,\n hiddenProjects: Array.isArray(parsed.hiddenProjects) ? parsed.hiddenProjects.filter((s: unknown) => typeof s === \"string\") : undefined,\n };\n } catch (err) {\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to load registry from ${REGISTRY_PATH} — using defaults:`, err);\n }\n return { sources: [] };\n }\n}\n\nfunction getDefaultSources(): WatchSource[] {\n const sources: WatchSource[] = [];\n\n // CLI flag via OBSERVER_WATCH_DIR (set by src/cli.ts — defaults to user's cwd)\n if (process.env.OBSERVER_WATCH_DIR) {\n sources.push({ path: process.env.OBSERVER_WATCH_DIR, depth: 3, label: \"cli\" });\n }\n\n // WATCH_DIR env (backwards-compatible single dir)\n if (process.env.WATCH_DIR) {\n sources.push({ path: process.env.WATCH_DIR, depth: 0, label: \"env\" });\n }\n\n // WATCH_DIRS env (comma-separated)\n if (process.env.WATCH_DIRS) {\n for (const dir of process.env.WATCH_DIRS.split(\",\")) {\n const trimmed = dir.trim();\n if (trimmed) sources.push({ path: trimmed, depth: 2 });\n }\n }\n\n // Default: parent of cwd — users typically run from inside a project dir\n // but want to observe ALL sibling projects in the parent folder\n if (sources.length === 0) {\n sources.push({\n path: path.resolve(process.cwd(), \"..\"),\n depth: 3,\n label: \"parent\",\n });\n }\n\n return sources;\n}\n\nexport async function getConfig(): Promise<ObserverConfig> {\n const now = Date.now();\n if (cachedConfig && now - cacheTime < CACHE_TTL) {\n return cachedConfig;\n }\n\n const registry = await loadRegistry();\n const defaultSources = getDefaultSources();\n\n // Merge: registry sources take priority, defaults as fallback\n // Deduplicate sources by normalized path to prevent duplicate discovery\n const rawSources = registry.sources.length > 0 ? registry.sources : defaultSources;\n const seen = new Set<string>();\n const sources = rawSources.filter((s) => {\n const normalized = path.resolve(s.path);\n if (seen.has(normalized)) return false;\n seen.add(normalized);\n return true;\n });\n\n // Priority: registry file > env vars > defaults\n const envPollInterval = process.env.OBSERVER_POLL_INTERVAL || process.env.POLL_INTERVAL;\n const envTheme = process.env.OBSERVER_DEFAULT_THEME || process.env.THEME;\n const envStaleThreshold = process.env.OBSERVER_STALE_THRESHOLD_MS;\n const envRecentWindow = process.env.OBSERVER_RECENT_WINDOW_MS;\n const envRetentionDays = process.env.OBSERVER_RETENTION_DAYS;\n\n cachedConfig = {\n sources,\n port: parseInt(process.env.OBSERVER_PORT || process.env.PORT || \"4800\", 10),\n pollInterval: registry.pollInterval ?? (envPollInterval ? parseInt(envPollInterval, 10) : 2000),\n theme: registry.theme ?? ((envTheme === \"dark\" || envTheme === \"light\" ? envTheme : \"dark\") as \"dark\" | \"light\"),\n staleThresholdMs: registry.staleThresholdMs ?? (envStaleThreshold ? parseInt(envStaleThreshold, 10) : 3600000),\n recentCompletionWindowMs: registry.recentCompletionWindowMs ?? (envRecentWindow ? parseInt(envRecentWindow, 10) : 14400000),\n retentionDays: registry.retentionDays ?? (envRetentionDays ? parseInt(envRetentionDays, 10) : 30),\n hiddenProjects: registry.hiddenProjects ?? [],\n };\n cacheTime = now;\n\n return cachedConfig;\n}\n","import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport { isNotFoundError, getConfig, type WatchSource } from \"./config-loader\";\n\nexport interface DiscoveredRun {\n runDir: string;\n source: WatchSource;\n projectName: string; // e.g. \"hockey_7_shifts\", \"podcast-intel\"\n projectPath: string; // full path to the project directory\n}\n\n// Discover all .a5c/runs/ directories within a source\nasync function discoverRunsInSource(source: WatchSource): Promise<string[]> {\n const results: string[] = [];\n\n async function scan(dir: string, currentDepth: number) {\n try {\n // Check if this directory itself IS an .a5c/runs dir (depth=0 means direct path)\n if (source.depth === 0) {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(dir, e.name));\n }\n\n // Check for .a5c/runs/ at this level\n const runsPath = path.join(dir, \".a5c\", \"runs\");\n try {\n const stat = await fs.stat(runsPath);\n if (stat.isDirectory()) {\n results.push(runsPath);\n }\n } catch {\n // Expected: no .a5c/runs directory at this level — skip silently\n }\n\n // Recurse into subdirectories if within depth\n if (currentDepth < source.depth) {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !entry.name.startsWith(\".\") &&\n entry.name !== \"node_modules\"\n ) {\n await scan(path.join(dir, entry.name), currentDepth + 1);\n }\n }\n }\n } catch (err) {\n if (!isNotFoundError(err)) {\n console.warn(`[config] Cannot scan directory ${dir} (depth=${currentDepth}):`, err);\n }\n }\n }\n\n if (source.depth === 0) {\n // Direct .a5c/runs path — just return runs inside it\n try {\n const entries = await fs.readdir(source.path, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(source.path, e.name));\n } catch (err) {\n console.warn(`[config] Cannot list runs in direct source ${source.path}:`, err);\n return [];\n }\n }\n\n await scan(source.path, 0);\n return results;\n}\n\n// Extract project name from a .a5c/runs/ path\nfunction extractProjectName(runsDir: string): { projectName: string; projectPath: string } {\n // runsDir is like /path/to/project/.a5c/runs\n // projectPath is /path/to/project\n const a5cDir = path.dirname(runsDir); // .a5c\n const projectPath = path.dirname(a5cDir); // project dir\n const projectName = path.basename(projectPath);\n return { projectName, projectPath };\n}\n\n// Cache discovery results to avoid repeated filesystem scanning\nlet discoveryCache: DiscoveredRun[] = [];\nlet discoveryCacheTime = 0;\nconst DISCOVERY_CACHE_TTL = 10000; // 10s — watcher handles real-time changes\n\n// Force re-discovery on next call (called when new runs are detected by watcher)\nexport function invalidateDiscoveryCache(): void {\n discoveryCache = [];\n discoveryCacheTime = 0;\n}\n\n// Get all run directories across all sources\nexport async function discoverAllRunDirs(): Promise<DiscoveredRun[]> {\n const now = Date.now();\n if (discoveryCache.length > 0 && now - discoveryCacheTime < DISCOVERY_CACHE_TTL) {\n return discoveryCache;\n }\n\n const config = await getConfig();\n const allRuns: DiscoveredRun[] = [];\n\n for (const source of config.sources) {\n if (source.depth === 0) {\n // Direct runs directory — list subdirs as individual runs\n // Project name: prefer run.json's projectName, fall back to source label or path\n const fallbackProjectName = source.label || path.basename(source.path);\n try {\n const entries = await fs.readdir(source.path, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n // Try to read projectName from run.json for more accurate project grouping\n let projectName = fallbackProjectName;\n try {\n const runJsonPath = path.join(source.path, entry.name, \"run.json\");\n const content = await fs.readFile(runJsonPath, \"utf-8\");\n const json = JSON.parse(content);\n if (json.projectName) {\n projectName = json.projectName;\n }\n } catch (err) {\n // run.json missing is expected for new runs; warn only on parse/permission errors\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to read run.json in ${path.join(source.path, entry.name)} — using fallback project name:`, err);\n }\n }\n allRuns.push({\n runDir: path.join(source.path, entry.name),\n source,\n projectName,\n projectPath: source.path,\n });\n }\n }\n } catch (err) {\n console.warn(`[config] Source directory not accessible ${source.path}:`, err);\n }\n } else {\n // Discover .a5c/runs/ directories within depth\n const runsDirs = await discoverRunsInSource(source);\n for (const runsDir of runsDirs) {\n const { projectName, projectPath } = extractProjectName(runsDir);\n try {\n const entries = await fs.readdir(runsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n allRuns.push({\n runDir: path.join(runsDir, entry.name),\n source,\n projectName,\n projectPath,\n });\n }\n }\n } catch (err) {\n console.warn(`[config] Cannot read runs directory ${runsDir}:`, err);\n }\n }\n }\n }\n\n // Deduplicate by runId (basename of runDir). When the same run ID appears\n // under multiple .a5c/runs/ directories (e.g. a \"ghost\" .a5c created by a\n // task execution in a subdirectory), keep the first occurrence — which is\n // the shallowest/earliest discovered and typically the one with full data\n // (run.json + journal).\n const seenRunIds = new Map<string, DiscoveredRun>();\n for (const run of allRuns) {\n const runId = path.basename(run.runDir);\n if (!seenRunIds.has(runId)) {\n seenRunIds.set(runId, run);\n } else {\n // Prefer the run directory that has a run.json (i.e. the real one)\n const existing = seenRunIds.get(runId)!;\n const existingHasRunJson = await fs.access(path.join(existing.runDir, \"run.json\")).then(() => true, () => false);\n if (!existingHasRunJson) {\n const candidateHasRunJson = await fs.access(path.join(run.runDir, \"run.json\")).then(() => true, () => false);\n if (candidateHasRunJson) {\n seenRunIds.set(runId, run);\n }\n }\n }\n }\n\n const result = Array.from(seenRunIds.values());\n discoveryCache = result;\n discoveryCacheTime = Date.now();\n return result;\n}\n\n// Discover all .a5c/runs/ parent directories (including empty ones).\n// Used by the watcher to set up watches on directories that don't have runs yet,\n// so that the very first run in a new project is detected immediately.\nexport async function discoverAllRunsParentDirs(): Promise<string[]> {\n const config = await getConfig();\n const allDirs: string[] = [];\n\n for (const source of config.sources) {\n if (source.depth === 0) {\n // Direct runs path — watch the source path itself\n try {\n await fs.access(source.path);\n allDirs.push(source.path);\n } catch (err) {\n console.warn(`[config] Watch source path not accessible ${source.path}:`, err);\n }\n } else {\n const runsDirs = await discoverRunsInSource(source);\n allDirs.push(...runsDirs);\n }\n }\n\n return allDirs;\n}\n","import { promises as fs } from \"fs\";\r\nimport path from \"path\";\r\n\r\n/** Return true when err represents a \"file/directory not found\" filesystem error. */\r\nfunction isNotFoundError(err: unknown): boolean {\r\n if (!(err instanceof Error)) return false;\r\n const code = (err as NodeJS.ErrnoException).code;\r\n return code === \"ENOENT\" || code === \"ENOTDIR\" || err.message.includes(\"ENOENT\");\r\n}\r\n\r\nimport type {\n Run,\n RunStatus,\n JournalEvent,\n TaskEffect,\r\n TaskDetail,\r\n TaskKind,\r\n RunDigest,\r\n EffectRequestedPayload,\r\n EffectResolvedPayload,\r\n RunCreatedPayload,\r\n} from \"@/types\";\nimport { getConfig } from \"@/lib/config-loader\";\n\nfunction parseTimestampMs(value: string | undefined): number | null {\n if (!value) return null;\n const ms = new Date(value).getTime();\n return Number.isFinite(ms) ? ms : null;\n}\n\nfunction normalizeInterval(startMs: number | null, endMs: number | null): { startMs: number; endMs: number } | null {\n if (startMs == null || endMs == null) return null;\n return {\n startMs,\n endMs: Math.max(endMs, startMs),\n };\n}\n\nfunction getTaskActiveWindow(task: {\n startedAt?: string;\n finishedAt?: string;\n requestedAt?: string;\n resolvedAt?: string;\n}): { startMs: number; endMs: number } | null {\n const explicitWindow = normalizeInterval(\n parseTimestampMs(task.startedAt),\n parseTimestampMs(task.finishedAt)\n );\n if (explicitWindow) return explicitWindow;\n\n return normalizeInterval(\n parseTimestampMs(task.requestedAt),\n parseTimestampMs(task.resolvedAt)\n );\n}\n\nfunction getTaskActiveDuration(task: {\n startedAt?: string;\n finishedAt?: string;\n requestedAt?: string;\n resolvedAt?: string;\n}): number | undefined {\n const window = getTaskActiveWindow(task);\n if (!window) return undefined;\n return window.endMs - window.startMs;\n}\n\nfunction getCoveredDurationMs(windows: Array<{ startMs: number; endMs: number }>): number {\n if (windows.length === 0) return 0;\n\n const sorted = [...windows].sort((a, b) => a.startMs - b.startMs);\n let covered = 0;\n let current = sorted[0];\n\n for (let i = 1; i < sorted.length; i++) {\n const next = sorted[i];\n if (next.startMs <= current.endMs) {\n current.endMs = Math.max(current.endMs, next.endMs);\n continue;\n }\n covered += current.endMs - current.startMs;\n current = next;\n }\n\n covered += current.endMs - current.startMs;\n return covered;\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\r\n } catch (err) {\r\n // ENOENT is expected for non-existent paths; warn on permission or other errors\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Unexpected error checking existence of ${filePath}:`, err);\r\n }\r\n return false;\r\n }\r\n}\r\n\r\nasync function readJsonSafe<T>(filePath: string, fallback: T | null | undefined): Promise<T | null | undefined> {\r\n try {\r\n const content = await fs.readFile(filePath, \"utf-8\");\r\n return JSON.parse(content) as T;\r\n } catch (err) {\r\n // ENOENT is expected for optional files; warn on parse errors or permission issues\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Failed to read/parse JSON from ${filePath}:`, err);\r\n }\r\n return fallback;\r\n }\r\n}\r\n\r\nasync function readTextSafe(filePath: string): Promise<string | undefined> {\r\n try {\r\n return await fs.readFile(filePath, \"utf-8\");\r\n } catch (err) {\r\n // ENOENT is expected for optional log files; warn on permission or other errors\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Failed to read text file ${filePath}:`, err);\r\n }\r\n return undefined;\r\n }\r\n}\r\n\r\n/** Maximum concurrent filesystem operations to prevent file descriptor exhaustion. */\r\nconst BATCH_CONCURRENCY_LIMIT = 50;\r\n\r\n/**\r\n * Execute an array of async factory functions with a concurrency limit.\r\n * Returns results in the same order as the input, using Promise.allSettled\r\n * semantics so that individual failures don't crash the batch.\r\n */\r\nasync function batchAllSettled<T>(\r\n factories: Array<() => Promise<T>>,\r\n limit: number = BATCH_CONCURRENCY_LIMIT\r\n): Promise<PromiseSettledResult<T>[]> {\r\n const results: PromiseSettledResult<T>[] = new Array(factories.length);\r\n let nextIndex = 0;\r\n\r\n async function worker() {\r\n while (nextIndex < factories.length) {\r\n const idx = nextIndex++;\r\n try {\r\n const value = await factories[idx]();\r\n results[idx] = { status: \"fulfilled\", value };\r\n } catch (reason) {\r\n results[idx] = { status: \"rejected\", reason };\r\n }\r\n }\r\n }\r\n\r\n const workerCount = Math.min(limit, factories.length);\r\n const workers: Promise<void>[] = [];\r\n for (let i = 0; i < workerCount; i++) {\r\n workers.push(worker());\r\n }\r\n await Promise.all(workers);\r\n return results;\r\n}\r\n\r\n// Normalize raw journal entry (which uses `data` and `recordedAt`) into our JournalEvent type\r\nfunction normalizeJournalEvent(raw: Record<string, unknown>, filename: string): JournalEvent | null {\r\n if (!raw || !raw.type) return null;\r\n\r\n // Parse seq and id from filename: \"000001.ULID.json\"\r\n const parts = filename.replace(/\\.json$/, \"\").split(\".\");\r\n const seq = parseInt(parts[0], 10) || 0;\r\n const id = parts[1] || \"\";\r\n\r\n return {\r\n seq,\r\n id,\r\n ts: (raw.recordedAt as string) || (raw.ts as string) || \"\",\r\n type: raw.type as JournalEvent[\"type\"],\r\n payload: (raw.data as Record<string, unknown>) || (raw.payload as Record<string, unknown>) || {},\r\n };\r\n}\r\n\r\n/** Result of an incremental journal parse. */\r\nexport interface IncrementalJournalResult {\r\n events: JournalEvent[];\r\n /** Number of JSON files in the journal directory after this parse. */\r\n fileCount: number;\r\n}\r\n\r\nexport async function parseJournalDir(\r\n journalPath: string\r\n): Promise<JournalEvent[]> {\r\n const result = await parseJournalDirIncremental(journalPath);\r\n return result.events;\r\n}\r\n\r\n/**\r\n * Incrementally parse a journal directory.\r\n *\r\n * When `previousEvents` and `previousFileCount` are supplied the function\r\n * skips files that were already parsed in a previous call. If the\r\n * directory now has *fewer* files than `previousFileCount` (truncation /\r\n * rotation) the journal is re-read from scratch.\r\n *\r\n * @param journalPath Path to the journal directory.\r\n * @param previousEvents Events returned by a prior call (used as base for merge).\r\n * @param previousFileCount Number of JSON files that existed during the prior call.\r\n * @returns Merged events array (sorted by seq) and the current file count.\r\n */\r\nexport async function parseJournalDirIncremental(\r\n journalPath: string,\r\n previousEvents?: JournalEvent[],\r\n previousFileCount?: number\r\n): Promise<IncrementalJournalResult> {\r\n if (!(await fileExists(journalPath))) return { events: [], fileCount: 0 };\r\n\r\n const files = await fs.readdir(journalPath);\r\n const jsonFiles = files.filter((f) => f.endsWith(\".json\")).sort();\r\n const currentFileCount = jsonFiles.length;\r\n\r\n // Determine whether we can do an incremental read.\r\n // Incremental is possible when we have cached state AND the file count\r\n // has not shrunk (truncation / rotation guard).\r\n const canIncremental =\r\n previousEvents !== undefined &&\r\n previousFileCount !== undefined &&\r\n previousFileCount >= 0 &&\r\n currentFileCount >= previousFileCount;\r\n\r\n if (canIncremental) {\r\n const newFilesStartIdx = previousFileCount!;\r\n\r\n // No new files — return the previous result as-is.\r\n if (newFilesStartIdx >= currentFileCount) {\r\n return { events: previousEvents!, fileCount: currentFileCount };\r\n }\r\n\r\n const newFiles = jsonFiles.slice(newFilesStartIdx);\r\n\r\n // Batch-read only the new files\r\n const readFactories = newFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n const newEvents: JournalEvent[] = [];\r\n for (let i = 0; i < newFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (raw) {\r\n const event = normalizeJournalEvent(raw, newFiles[i]);\r\n if (event) newEvents.push(event);\r\n }\r\n }\r\n\r\n // Merge: previousEvents is already sorted; new events are appended and\r\n // the full array is re-sorted to guarantee correctness.\r\n const merged = [...previousEvents!, ...newEvents].sort((a, b) => a.seq - b.seq);\r\n return { events: merged, fileCount: currentFileCount };\r\n }\r\n\r\n // Full re-read (first call, or truncation detected).\r\n const readFactories = jsonFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n const events: JournalEvent[] = [];\r\n for (let i = 0; i < jsonFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (raw) {\r\n const event = normalizeJournalEvent(raw, jsonFiles[i]);\r\n if (event) events.push(event);\r\n }\r\n }\r\n\r\n return { events: events.sort((a, b) => a.seq - b.seq), fileCount: currentFileCount };\r\n}\r\n\r\n/** Options for incremental run parsing. */\r\nexport interface IncrementalRunOptions {\r\n previousEvents?: JournalEvent[];\r\n previousFileCount?: number;\r\n}\r\n\r\n/** Extended Run result that includes the journal file count for caching. */\r\nexport interface ParseRunResult extends Run {\r\n /** Number of journal files parsed — used by the cache layer for incremental reads. */\r\n _journalFileCount: number;\r\n}\r\n\r\nexport async function parseRunDir(\r\n runPath: string,\r\n incremental?: IncrementalRunOptions\r\n): Promise<ParseRunResult> {\r\n const runJson = await readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"run.json\"),\r\n {}\r\n );\r\n\r\n const journalResult = await parseJournalDirIncremental(\r\n path.join(runPath, \"journal\"),\r\n incremental?.previousEvents,\r\n incremental?.previousFileCount\r\n );\r\n const events = journalResult.events;\r\n\r\n // Extract run info from events\r\n const runCreated = events.find((e) => e.type === \"RUN_CREATED\");\r\n const runCompleted = events.find((e) => e.type === \"RUN_COMPLETED\");\r\n const runFailed = events.find((e) => e.type === \"RUN_FAILED\");\r\n\r\n const createdPayload = (runCreated?.payload ||\r\n {}) as unknown as RunCreatedPayload;\r\n\r\n // Build task map from events — first pass: collect all requested/resolved info\r\n const taskMap = new Map<string, TaskEffect>();\r\n const requestedPayloads: EffectRequestedPayload[] = [];\r\n\r\n for (const event of events) {\r\n if (event.type === \"EFFECT_REQUESTED\") {\r\n const p = event.payload as unknown as EffectRequestedPayload;\r\n requestedPayloads.push(p);\r\n taskMap.set(p.effectId, {\r\n effectId: p.effectId,\r\n kind: p.kind,\r\n title: p.label || p.taskId,\r\n label: p.label || p.taskId,\r\n status: \"requested\",\r\n invocationKey: p.invocationKey,\r\n stepId: p.stepId,\r\n taskId: p.taskId,\r\n requestedAt: event.ts,\r\n });\r\n }\r\n\r\n if (event.type === \"EFFECT_RESOLVED\") {\r\n const p = event.payload as unknown as EffectResolvedPayload;\r\n const task = taskMap.get(p.effectId);\r\n if (task) {\n task.status = p.status === \"ok\" ? \"resolved\" : \"error\";\n task.resolvedAt = event.ts;\n task.startedAt = p.startedAt;\n task.finishedAt = p.finishedAt;\n task.duration = getTaskActiveDuration({\n startedAt: p.startedAt,\n finishedAt: p.finishedAt,\n requestedAt: task.requestedAt,\n resolvedAt: event.ts,\n });\n if (p.error) {\n task.error = {\n name: p.error.name,\n message: p.error.message,\r\n stack: p.error.stack,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Batch-read all task.json files in parallel for EFFECT_REQUESTED tasks\r\n if (requestedPayloads.length > 0) {\r\n const taskDefFactories = requestedPayloads.map(\r\n (p) => () =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", p.effectId, \"task.json\"),\r\n null\r\n )\r\n );\r\n const taskDefResults = await batchAllSettled(taskDefFactories);\r\n\r\n for (let i = 0; i < requestedPayloads.length; i++) {\r\n const p = requestedPayloads[i];\r\n const result = taskDefResults[i];\r\n const taskDef = result.status === \"fulfilled\" ? result.value : null;\r\n if (taskDef) {\r\n const task = taskMap.get(p.effectId)!;\r\n task.title = (taskDef.title as string) || task.title;\r\n if (taskDef.agent && typeof taskDef.agent === \"object\") {\r\n const agentDef = taskDef.agent as Record<string, unknown>;\r\n task.agent = {\r\n name: (agentDef.name as string) || \"unknown\",\r\n prompt: agentDef.prompt as NonNullable<TaskEffect[\"agent\"]>[\"prompt\"],\r\n };\r\n }\r\n // Extract breakpoint question from inputs for breakpoint tasks\r\n if (p.kind === \"breakpoint\") {\r\n const inputs = taskDef.inputs as Record<string, unknown> | undefined;\r\n if (inputs && typeof inputs.question === \"string\") {\r\n task.breakpointQuestion = inputs.question;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n const tasks = Array.from(taskMap.values());\r\n const completedTasks = tasks.filter((t) => t.status === \"resolved\").length;\r\n const failedTasks = tasks.filter((t) => t.status === \"error\").length;\r\n\r\n // Task 1.2: Extract failed step name from the first task that resolved with error\r\n const firstFailedTask = tasks.find((t) => t.status === \"error\");\r\n const failedStep = firstFailedTask\r\n ? firstFailedTask.title || firstFailedTask.label || firstFailedTask.stepId\r\n : undefined;\r\n\r\n // Extract failure details from RUN_FAILED event or last failed EFFECT_RESOLVED\r\n let failureError: string | undefined;\r\n let failureMessage: string | undefined;\r\n\r\n if (runFailed) {\r\n const failPayload = runFailed.payload as Record<string, unknown>;\r\n const runError = failPayload.error as { name?: string; message?: string; stack?: string } | undefined;\r\n if (runError) {\r\n failureError = runError.name || \"Error\";\r\n failureMessage = runError.message || runError.stack || undefined;\r\n }\r\n }\r\n\r\n // If we still don't have a message, look at the last EFFECT_RESOLVED with error status\r\n if (!failureMessage) {\r\n const lastFailedEffect = [...events]\r\n .reverse()\r\n .find((e) => e.type === \"EFFECT_RESOLVED\" && (e.payload as Record<string, unknown>).status === \"error\");\r\n if (lastFailedEffect) {\r\n const effectPayload = lastFailedEffect.payload as Record<string, unknown>;\r\n const effectError = effectPayload.error as { name?: string; message?: string; stack?: string } | undefined;\r\n if (effectError) {\r\n failureError = failureError || effectError.name || \"Error\";\r\n failureMessage = effectError.message || effectError.stack || undefined;\r\n }\r\n }\r\n }\r\n\r\n let status: RunStatus = \"pending\";\r\n if (runCompleted) status = \"completed\";\r\n else if (runFailed) status = \"failed\";\r\n else if (tasks.some((t) => t.status === \"requested\")) status = \"waiting\";\r\n\r\n // Task 1.3: Extract breakpoint question from pending breakpoint tasks\r\n let breakpointQuestion: string | undefined;\r\n if (status === \"waiting\") {\r\n const pendingBreakpoint = tasks.find(\r\n (t) => t.kind === \"breakpoint\" && t.status === \"requested\"\r\n );\r\n if (pendingBreakpoint?.breakpointQuestion) {\r\n breakpointQuestion = pendingBreakpoint.breakpointQuestion;\r\n }\r\n }\r\n\r\n // Determine waitingKind: check the last requested (pending) task\r\n let waitingKind: 'breakpoint' | 'task' | undefined;\r\n if (status === \"waiting\") {\r\n const requestedTasks = tasks.filter((t) => t.status === \"requested\");\r\n const lastRequested = requestedTasks[requestedTasks.length - 1];\r\n if (lastRequested) {\r\n waitingKind = lastRequested.kind === \"breakpoint\" ? \"breakpoint\" : \"task\";\r\n }\r\n }\r\n\r\n const createdAt = runCreated?.ts || \"\";\n const lastEvent = events[events.length - 1];\n\n let duration: number | undefined;\n const taskWindows = tasks\n .map((task) => getTaskActiveWindow(task))\n .filter((window): window is { startMs: number; endMs: number } => window !== null);\n if (taskWindows.length > 0) {\n duration = getCoveredDurationMs(taskWindows);\n } else if (createdAt && (runCompleted || runFailed)) {\n const endTs = (runCompleted || runFailed)!.ts;\n duration = new Date(endTs).getTime() - new Date(createdAt).getTime();\n } else if (createdAt && lastEvent) {\n duration =\n new Date(lastEvent.ts).getTime() - new Date(createdAt).getTime();\n }\n\r\n // Detect staleness for waiting or pending runs\r\n let isStale: boolean | undefined;\r\n if (status === \"waiting\" || status === \"pending\") {\r\n const updatedAtTs = lastEvent?.ts || createdAt;\r\n if (updatedAtTs) {\r\n const config = await getConfig();\r\n const timeSinceUpdate = Date.now() - new Date(updatedAtTs).getTime();\r\n if (timeSinceUpdate > config.staleThresholdMs) {\r\n isStale = true;\r\n }\r\n }\r\n }\r\n\r\n // Detect orphaned runs: all tasks resolved but no terminal event\r\n // (process likely crashed before writing RUN_COMPLETED)\r\n if (status === \"pending\" && tasks.length > 0 && !tasks.some((t) => t.status === \"requested\")) {\r\n isStale = true;\r\n }\r\n\r\n return {\r\n runId: createdPayload.runId || path.basename(runPath),\r\n processId:\r\n createdPayload.processId ||\r\n (runJson?.processId as string) ||\r\n \"unknown\",\r\n status,\r\n createdAt,\r\n updatedAt: lastEvent?.ts || createdAt,\r\n completedAt: (runCompleted || runFailed)?.ts,\r\n tasks,\r\n events,\r\n totalTasks: tasks.length,\r\n completedTasks,\r\n failedTasks,\r\n duration,\r\n failedStep,\r\n failureError,\r\n failureMessage,\r\n breakpointQuestion,\r\n isStale,\r\n waitingKind,\r\n _journalFileCount: journalResult.fileCount,\r\n };\r\n}\r\n\r\nexport async function parseTaskDetail(\r\n runPath: string,\r\n effectId: string\r\n): Promise<TaskDetail | null> {\r\n const taskDir = path.join(runPath, \"tasks\", effectId);\r\n if (!(await fileExists(taskDir))) return null;\r\n\r\n // Read all 5 task files + journal in parallel with Promise.allSettled\r\n const [\r\n taskDefResult,\r\n inputResult,\r\n resultResult,\r\n stdoutResult,\r\n stderrResult,\r\n journalEventsResult,\r\n ] = await Promise.allSettled([\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"task.json\"), null),\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"input.json\"), undefined),\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"result.json\"), undefined),\r\n readTextSafe(path.join(taskDir, \"stdout.log\")),\r\n readTextSafe(path.join(taskDir, \"stderr.log\")),\r\n parseJournalDir(path.join(runPath, \"journal\")),\r\n ]);\r\n\r\n const taskDef = taskDefResult.status === \"fulfilled\" ? taskDefResult.value : null;\r\n const input = inputResult.status === \"fulfilled\" ? inputResult.value : undefined;\r\n const result = resultResult.status === \"fulfilled\" ? resultResult.value : undefined;\r\n const stdout = stdoutResult.status === \"fulfilled\" ? stdoutResult.value : undefined;\r\n const stderr = stderrResult.status === \"fulfilled\" ? stderrResult.value : undefined;\r\n const journalEvents = journalEventsResult.status === \"fulfilled\" ? journalEventsResult.value : [];\r\n\r\n // Extract timing from result.json\r\n const resultStartedAt = result?.startedAt as string | undefined;\r\n const resultFinishedAt = result?.finishedAt as string | undefined;\r\n const requestedEvent = journalEvents.find(\r\n (e) => e.type === \"EFFECT_REQUESTED\" && (e.payload as Record<string, unknown>).effectId === effectId\r\n );\r\n const resolvedEvent = journalEvents.find(\r\n (e) => e.type === \"EFFECT_RESOLVED\" && (e.payload as Record<string, unknown>).effectId === effectId\r\n );\r\n\r\n const requestedAt = requestedEvent?.ts || \"\";\r\n const resolvedAt = resolvedEvent?.ts;\n\n const duration = getTaskActiveDuration({\n startedAt: resultStartedAt,\n finishedAt: resultFinishedAt,\n requestedAt,\n resolvedAt,\n });\n\r\n // Use inputs from task.json if separate input.json doesn't exist\r\n const resolvedInput = input ?? (taskDef?.inputs as Record<string, unknown> | undefined);\r\n\r\n // Extract breakpoint payload for breakpoint tasks\r\n const kind = (taskDef?.kind as TaskKind) || \"agent\";\r\n let breakpointPayload: import(\"@/types\").BreakpointPayload | undefined;\r\n if (kind === \"breakpoint\" && resolvedInput) {\r\n breakpointPayload = {\r\n question: (resolvedInput.question as string) || \"Approval required\",\r\n title: (resolvedInput.title as string) || (taskDef?.title as string) || \"Breakpoint\",\r\n options: Array.isArray(resolvedInput.options) ? (resolvedInput.options as string[]) : undefined,\r\n context: resolvedInput.context as import(\"@/types\").BreakpointPayload[\"context\"],\r\n };\r\n }\r\n\r\n // Determine error status from result or journal\r\n const resolvedPayload = resolvedEvent?.payload as Record<string, unknown> | undefined;\r\n const isError = result\r\n ? (result.status === \"error\")\r\n : (resolvedPayload?.status === \"error\");\r\n\r\n return {\r\n effectId,\r\n kind,\r\n title: (taskDef?.title as string) || effectId,\r\n label: (taskDef?.title as string) || effectId,\r\n status: resolvedEvent ? (isError ? \"error\" : \"resolved\") : \"requested\",\r\n invocationKey: (taskDef?.invocationKey as string) || \"\",\r\n stepId: (taskDef?.stepId as string) || \"\",\r\n taskId: (taskDef?.taskId as string) || \"\",\r\n requestedAt,\r\n resolvedAt,\r\n startedAt: resultStartedAt,\r\n finishedAt: resultFinishedAt,\r\n duration,\r\n input: resolvedInput,\r\n result: result ?? undefined,\r\n stdout,\r\n stderr,\r\n taskDef: taskDef ?? undefined,\r\n breakpoint: breakpointPayload,\r\n breakpointQuestion: breakpointPayload?.question,\r\n };\r\n}\r\n\r\nexport async function getRunDigest(runPath: string): Promise<RunDigest> {\r\n const journalPath = path.join(runPath, \"journal\");\r\n let latestSeq = 0;\r\n let status: RunStatus = \"pending\";\r\n let taskCount = 0;\r\n let completedTasks = 0;\r\n let updatedAt = \"\";\r\n\r\n const requestedBreakpoints = new Set<string>();\r\n const resolvedEffects = new Set<string>();\r\n const breakpointEffectIds = new Set<string>();\r\n // Track requested effects and their kinds for waitingKind determination\r\n const requestedEffects: Array<{ effectId: string; kind: string }> = [];\r\n\r\n if (await fileExists(journalPath)) {\r\n const files = await fs.readdir(journalPath);\r\n const jsonFiles = files.filter((f) => f.endsWith(\".json\")).sort();\r\n latestSeq = jsonFiles.length;\r\n\r\n // Batch-read all journal files in parallel with concurrency limit\r\n const readFactories = jsonFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n // Process results sequentially to maintain event ordering for updatedAt\r\n for (let i = 0; i < jsonFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (!raw) continue;\r\n const event = normalizeJournalEvent(raw, jsonFiles[i]);\r\n if (!event) continue;\r\n updatedAt = event.ts;\r\n if (event.type === \"EFFECT_REQUESTED\") {\r\n taskCount++;\r\n const data = event.payload as Record<string, unknown>;\r\n const effectId = data.effectId as string;\r\n const kind = (data.kind as string) || \"agent\";\r\n requestedEffects.push({ effectId, kind });\r\n if (data.kind === \"breakpoint\") {\r\n requestedBreakpoints.add(effectId);\r\n breakpointEffectIds.add(effectId);\r\n }\r\n }\r\n if (event.type === \"EFFECT_RESOLVED\") {\r\n completedTasks++;\r\n const data = event.payload as Record<string, unknown>;\r\n resolvedEffects.add(data.effectId as string);\r\n }\r\n if (event.type === \"RUN_COMPLETED\") status = \"completed\";\r\n if (event.type === \"RUN_FAILED\") status = \"failed\";\r\n }\r\n\r\n if (status === \"pending\" && taskCount > 0) status = \"waiting\";\r\n }\r\n\r\n // Count pending breakpoints (requested but not yet resolved).\r\n // Also check result.json — the dashboard writes it on approve but can't\r\n // write journal events, so the journal alone may lag behind.\r\n let pendingBreakpoints = 0;\r\n if (requestedBreakpoints.size > 0) {\r\n const unresolvedBps = [...requestedBreakpoints].filter(\r\n (id) => !resolvedEffects.has(id)\r\n );\r\n if (unresolvedBps.length > 0) {\r\n const resultChecks = await Promise.all(\r\n unresolvedBps.map((id) =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", id, \"result.json\"),\r\n null\r\n )\r\n )\r\n );\r\n for (let i = 0; i < unresolvedBps.length; i++) {\r\n if (resultChecks[i] && resultChecks[i]!.status === \"ok\") {\r\n resolvedEffects.add(unresolvedBps[i]);\r\n } else {\r\n pendingBreakpoints++;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract breakpoint question and effectId from pending breakpoint tasks — batch-read all at once\r\n let breakpointQuestion: string | undefined;\r\n let breakpointEffectId: string | undefined;\r\n if (status === \"waiting\" && breakpointEffectIds.size > 0) {\r\n const pendingBpIds = [...breakpointEffectIds].filter(\r\n (id) => !resolvedEffects.has(id)\r\n );\r\n if (pendingBpIds.length > 0) {\r\n // Store the first pending breakpoint effectId regardless of question\r\n breakpointEffectId = pendingBpIds[0];\r\n\r\n const bpFactories = pendingBpIds.map(\r\n (effectId) => () =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", effectId, \"task.json\"),\r\n null\r\n )\r\n );\r\n const bpResults = await batchAllSettled(bpFactories);\r\n\r\n // Use the first pending breakpoint question found\r\n for (let i = 0; i < pendingBpIds.length; i++) {\r\n const result = bpResults[i];\r\n const taskDef = result.status === \"fulfilled\" ? result.value : null;\r\n if (taskDef) {\r\n const inputs = taskDef.inputs as Record<string, unknown> | undefined;\r\n if (inputs && typeof inputs.question === \"string\") {\r\n breakpointQuestion = inputs.question;\r\n breakpointEffectId = pendingBpIds[i];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Determine waitingKind from the last requested (pending) effect\r\n let waitingKind: 'breakpoint' | 'task' | undefined;\r\n if (status === \"waiting\") {\r\n // Find the last requested effect that hasn't been resolved\r\n const pendingEffects = requestedEffects.filter(\r\n (e) => !resolvedEffects.has(e.effectId)\r\n );\r\n const lastPending = pendingEffects[pendingEffects.length - 1];\r\n if (lastPending) {\r\n waitingKind = lastPending.kind === \"breakpoint\" ? \"breakpoint\" : \"task\";\r\n }\r\n }\r\n\r\n // Detect staleness for waiting or pending runs\r\n let isStale: boolean | undefined;\r\n if (status === \"waiting\" || status === \"pending\") {\r\n if (updatedAt) {\r\n const config = await getConfig();\r\n const timeSinceUpdate = Date.now() - new Date(updatedAt).getTime();\r\n if (timeSinceUpdate > config.staleThresholdMs) {\r\n isStale = true;\r\n }\r\n }\r\n }\r\n\r\n // Detect orphaned runs: all effects resolved but no terminal event\r\n if (status === \"waiting\" && taskCount > 0 && completedTasks >= taskCount) {\r\n isStale = true;\r\n }\r\n\r\n return {\r\n runId: path.basename(runPath),\r\n latestSeq,\r\n status,\r\n taskCount,\r\n completedTasks,\r\n updatedAt,\r\n pendingBreakpoints,\r\n breakpointQuestion,\r\n breakpointEffectId,\r\n isStale,\r\n waitingKind,\r\n };\r\n}\r\n\r\nexport async function getRunIds(runsPath: string): Promise<string[]> {\r\n if (!(await fileExists(runsPath))) return [];\r\n const entries = await fs.readdir(runsPath, { withFileTypes: true });\r\n return entries\r\n .filter((e) => e.isDirectory())\r\n .map((e) => e.name)\r\n .sort()\r\n .reverse();\r\n}\r\n"],"names":["isNotFoundError","err","Error","code","message","includes","REGISTRY_PATH","process","env","OBSERVER_REGISTRY","join","homedir","cachedConfig","cacheTime","CACHE_TTL","invalidateConfigCache","writeConfig","data","dir","dirname","mkdir","recursive","existing","content","readFile","JSON","parse","console","warn","merged","sources","pollInterval","undefined","theme","staleThresholdMs","recentCompletionWindowMs","retentionDays","hiddenProjects","writeFile","stringify","loadRegistry","parsed","Array","isArray","map","s","path","String","depth","label","filter","getDefaultSources","OBSERVER_WATCH_DIR","push","WATCH_DIR","WATCH_DIRS","split","trimmed","trim","length","resolve","cwd","getConfig","now","Date","registry","defaultSources","rawSources","seen","Set","normalized","has","add","envPollInterval","OBSERVER_POLL_INTERVAL","POLL_INTERVAL","envTheme","OBSERVER_DEFAULT_THEME","THEME","envStaleThreshold","OBSERVER_STALE_THRESHOLD_MS","envRecentWindow","OBSERVER_RECENT_WINDOW_MS","envRetentionDays","OBSERVER_RETENTION_DAYS","port","parseInt","OBSERVER_PORT","PORT","discoverRunsInSource","source","results","scan","currentDepth","entries","readdir","withFileTypes","e","isDirectory","name","runsPath","stat","entry","startsWith","extractProjectName","runsDir","a5cDir","projectPath","projectName","basename","discoveryCache","discoveryCacheTime","DISCOVERY_CACHE_TTL","invalidateDiscoveryCache","discoverAllRunDirs","config","allRuns","fallbackProjectName","runJsonPath","json","runDir","runsDirs","seenRunIds","Map","run","runId","set","get","existingHasRunJson","access","then","candidateHasRunJson","result","from","values","discoverAllRunsParentDirs","allDirs","parseTimestampMs","value","ms","getTime","Number","isFinite","normalizeInterval","startMs","endMs","Math","max","getTaskActiveWindow","task","explicitWindow","startedAt","finishedAt","requestedAt","resolvedAt","getTaskActiveDuration","window","getCoveredDurationMs","windows","sorted","sort","a","b","covered","current","i","next","fileExists","filePath","readJsonSafe","fallback","readTextSafe","BATCH_CONCURRENCY_LIMIT","batchAllSettled","factories","limit","nextIndex","worker","idx","status","reason","workerCount","min","workers","Promise","all","normalizeJournalEvent","raw","filename","type","parts","replace","seq","id","ts","recordedAt","payload","parseJournalDir","journalPath","parseJournalDirIncremental","events","previousEvents","previousFileCount","fileCount","files","jsonFiles","f","endsWith","currentFileCount","canIncremental","newFilesStartIdx","newFiles","slice","readFactories","file","settled","newEvents","event","parseRunDir","runPath","incremental","runJson","journalResult","runCreated","find","runCompleted","runFailed","createdPayload","taskMap","requestedPayloads","p","effectId","kind","title","taskId","invocationKey","stepId","duration","error","stack","taskDefFactories","taskDefResults","taskDef","agent","agentDef","prompt","inputs","question","breakpointQuestion","tasks","completedTasks","t","failedTasks","firstFailedTask","failedStep","failureError","failureMessage","failPayload","runError","lastFailedEffect","reverse","effectPayload","effectError","some","pendingBreakpoint","waitingKind","requestedTasks","lastRequested","createdAt","lastEvent","taskWindows","endTs","isStale","updatedAtTs","timeSinceUpdate","processId","updatedAt","completedAt","totalTasks","_journalFileCount","parseTaskDetail","taskDir","taskDefResult","inputResult","resultResult","stdoutResult","stderrResult","journalEventsResult","allSettled","input","stdout","stderr","journalEvents","resultStartedAt","resultFinishedAt","requestedEvent","resolvedEvent","resolvedInput","breakpointPayload","options","context","resolvedPayload","isError","breakpoint","getRunDigest","latestSeq","taskCount","requestedBreakpoints","resolvedEffects","breakpointEffectIds","requestedEffects","pendingBreakpoints","size","unresolvedBps","resultChecks","breakpointEffectId","pendingBpIds","bpFactories","bpResults","pendingEffects","lastPending","getRunIds"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
module.exports=[37315,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(46786);function a(e){if(!(e instanceof Error))return!1;let t=e.code;return"ENOENT"===t||"ENOTDIR"===t||e.message.includes("ENOENT")}let s=process.env.OBSERVER_REGISTRY||n.default.join(r.default.homedir(),".a5c","observer.json"),i=null,l=0;async function o(e){let r=n.default.dirname(s);await t.promises.mkdir(r,{recursive:!0});let i={};try{let e=await t.promises.readFile(s,"utf-8");i=JSON.parse(e)}catch(e){a(e)||console.warn(`[config] Failed to read existing config at ${s} before merge:`,e)}let l={...i,sources:e.sources,...void 0!==e.pollInterval?{pollInterval:e.pollInterval}:{},...void 0!==e.theme?{theme:e.theme}:{},...void 0!==e.staleThresholdMs?{staleThresholdMs:e.staleThresholdMs}:{},...void 0!==e.recentCompletionWindowMs?{recentCompletionWindowMs:e.recentCompletionWindowMs}:{},...void 0!==e.retentionDays?{retentionDays:e.retentionDays}:{},...void 0!==e.hiddenProjects?{hiddenProjects:e.hiddenProjects}:{}};await t.promises.writeFile(s,JSON.stringify(l,null,2)+"\n","utf-8")}async function d(){try{let e=await t.promises.readFile(s,"utf-8"),n=JSON.parse(e);return{sources:Array.isArray(n.sources)?n.sources.map(e=>({path:String(e.path||""),depth:"number"==typeof e.depth?e.depth:2,label:e.label?String(e.label):void 0})):[],pollInterval:"number"==typeof n.pollInterval?n.pollInterval:void 0,theme:"dark"===n.theme||"light"===n.theme?n.theme:void 0,staleThresholdMs:"number"==typeof n.staleThresholdMs?n.staleThresholdMs:void 0,recentCompletionWindowMs:"number"==typeof n.recentCompletionWindowMs?n.recentCompletionWindowMs:void 0,retentionDays:"number"==typeof n.retentionDays?n.retentionDays:void 0,hiddenProjects:Array.isArray(n.hiddenProjects)?n.hiddenProjects.filter(e=>"string"==typeof e):void 0}}catch(e){return a(e)||console.warn(`[config] Failed to load registry from ${s} — using defaults:`,e),{sources:[]}}}async function u(){let e=Date.now();if(i&&e-l<1e4)return i;let t=await d(),r=function(){let e=[];if(process.env.OBSERVER_WATCH_DIR&&e.push({path:process.env.OBSERVER_WATCH_DIR,depth:3,label:"cli"}),process.env.WATCH_DIR&&e.push({path:process.env.WATCH_DIR,depth:0,label:"env"}),process.env.WATCH_DIRS)for(let t of process.env.WATCH_DIRS.split(",")){let n=t.trim();n&&e.push({path:n,depth:2})}return 0===e.length&&e.push({path:n.default.resolve(process.cwd(),".."),depth:3,label:"parent"}),e}(),a=t.sources.length>0?t.sources:r,s=new Set,o=a.filter(e=>{let t=n.default.resolve(e.path);return!s.has(t)&&(s.add(t),!0)}),u=process.env.OBSERVER_POLL_INTERVAL||process.env.POLL_INTERVAL,f=process.env.OBSERVER_DEFAULT_THEME||process.env.THEME,p=process.env.OBSERVER_STALE_THRESHOLD_MS,c=process.env.OBSERVER_RECENT_WINDOW_MS,h=process.env.OBSERVER_RETENTION_DAYS;return i={sources:o,port:parseInt(process.env.OBSERVER_PORT||process.env.PORT||"4800",10),pollInterval:t.pollInterval??(u?parseInt(u,10):2e3),theme:t.theme??("dark"===f||"light"===f?f:"dark"),staleThresholdMs:t.staleThresholdMs??(p?parseInt(p,10):36e5),recentCompletionWindowMs:t.recentCompletionWindowMs??(c?parseInt(c,10):144e5),retentionDays:t.retentionDays??(h?parseInt(h,10):30),hiddenProjects:t.hiddenProjects??[]},l=e,i}e.s(["getConfig",0,u,"invalidateConfigCache",0,function(){i=null,l=0},"isNotFoundError",0,a,"writeConfig",0,o])},40564,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(37315);function a(e){if(!(e instanceof Error))return!1;let t=e.code;return"ENOENT"===t||"ENOTDIR"===t||e.message.includes("ENOENT")}function s(e){if(!e)return null;let t=new Date(e).getTime();return Number.isFinite(t)?t:null}function i(e,t){return null==e||null==t?null:{startMs:e,endMs:Math.max(t,e)}}function l(e){let t=i(s(e.startedAt),s(e.finishedAt));return t||i(s(e.requestedAt),s(e.resolvedAt))}function o(e){let t=l(e);if(t)return t.endMs-t.startMs}async function d(e){try{return await t.promises.access(e),!0}catch(t){return a(t)||console.warn(`[parser] Unexpected error checking existence of ${e}:`,t),!1}}async function u(e,n){try{let n=await t.promises.readFile(e,"utf-8");return JSON.parse(n)}catch(t){return a(t)||console.warn(`[parser] Failed to read/parse JSON from ${e}:`,t),n}}async function f(e){try{return await t.promises.readFile(e,"utf-8")}catch(t){a(t)||console.warn(`[parser] Failed to read text file ${e}:`,t);return}}async function p(e,t=50){let n=Array(e.length),r=0;async function a(){for(;r<e.length;){let t=r++;try{let r=await e[t]();n[t]={status:"fulfilled",value:r}}catch(e){n[t]={status:"rejected",reason:e}}}}let s=Math.min(t,e.length),i=[];for(let e=0;e<s;e++)i.push(a());return await Promise.all(i),n}function c(e,t){if(!e||!e.type)return null;let n=t.replace(/\.json$/,"").split(".");return{seq:parseInt(n[0],10)||0,id:n[1]||"",ts:e.recordedAt||e.ts||"",type:e.type,payload:e.data||e.payload||{}}}async function h(e){return(await m(e)).events}async function m(e,r,a){if(!await d(e))return{events:[],fileCount:0};let s=(await t.promises.readdir(e)).filter(e=>e.endsWith(".json")).sort(),i=s.length;if(void 0!==r&&void 0!==a&&a>=0&&i>=a){if(a>=i)return{events:r,fileCount:i};let t=s.slice(a),l=t.map(t=>()=>u(n.default.join(e,t),null)),o=await p(l),d=[];for(let e=0;e<t.length;e++){let n=o[e],r="fulfilled"===n.status?n.value:null;if(r){let n=c(r,t[e]);n&&d.push(n)}}return{events:[...r,...d].sort((e,t)=>e.seq-t.seq),fileCount:i}}let l=s.map(t=>()=>u(n.default.join(e,t),null)),o=await p(l),f=[];for(let e=0;e<s.length;e++){let t=o[e],n="fulfilled"===t.status?t.value:null;if(n){let t=c(n,s[e]);t&&f.push(t)}}return{events:f.sort((e,t)=>e.seq-t.seq),fileCount:i}}async function y(e,t){let a,s,i,d,f,c,h=await u(n.default.join(e,"run.json"),{}),y=await m(n.default.join(e,"journal"),t?.previousEvents,t?.previousFileCount),g=y.events,w=g.find(e=>"RUN_CREATED"===e.type),v=g.find(e=>"RUN_COMPLETED"===e.type),E=g.find(e=>"RUN_FAILED"===e.type),D=w?.payload||{},T=new Map,j=[];for(let e of g){if("EFFECT_REQUESTED"===e.type){let t=e.payload;j.push(t),T.set(t.effectId,{effectId:t.effectId,kind:t.kind,title:t.label||t.taskId,label:t.label||t.taskId,status:"requested",invocationKey:t.invocationKey,stepId:t.stepId,taskId:t.taskId,requestedAt:e.ts})}if("EFFECT_RESOLVED"===e.type){let t=e.payload,n=T.get(t.effectId);n&&(n.status="ok"===t.status?"resolved":"error",n.resolvedAt=e.ts,n.startedAt=t.startedAt,n.finishedAt=t.finishedAt,n.duration=o({startedAt:t.startedAt,finishedAt:t.finishedAt,requestedAt:n.requestedAt,resolvedAt:e.ts}),t.error&&(n.error={name:t.error.name,message:t.error.message,stack:t.error.stack}))}}if(j.length>0){let t=j.map(t=>()=>u(n.default.join(e,"tasks",t.effectId,"task.json"),null)),r=await p(t);for(let e=0;e<j.length;e++){let t=j[e],n=r[e],a="fulfilled"===n.status?n.value:null;if(a){let e=T.get(t.effectId);if(e.title=a.title||e.title,a.agent&&"object"==typeof a.agent){let t=a.agent;e.agent={name:t.name||"unknown",prompt:t.prompt}}if("breakpoint"===t.kind){let t=a.inputs;t&&"string"==typeof t.question&&(e.breakpointQuestion=t.question)}}}}let I=Array.from(T.values()),k=I.filter(e=>"resolved"===e.status).length,A=I.filter(e=>"error"===e.status).length,R=I.find(e=>"error"===e.status),C=R?R.title||R.label||R.stepId:void 0;if(E){let e=E.payload.error;e&&(a=e.name||"Error",s=e.message||e.stack||void 0)}if(!s){let e=[...g].reverse().find(e=>"EFFECT_RESOLVED"===e.type&&"error"===e.payload.status);if(e){let t=e.payload.error;t&&(a=a||t.name||"Error",s=t.message||t.stack||void 0)}}let b="pending";if(v?b="completed":E?b="failed":I.some(e=>"requested"===e.status)&&(b="waiting"),"waiting"===b){let e=I.find(e=>"breakpoint"===e.kind&&"requested"===e.status);e?.breakpointQuestion&&(i=e.breakpointQuestion)}if("waiting"===b){let e=I.filter(e=>"requested"===e.status),t=e[e.length-1];t&&(d="breakpoint"===t.kind?"breakpoint":"task")}let M=w?.ts||"",F=g[g.length-1],S=I.map(e=>l(e)).filter(e=>null!==e);if(S.length>0?f=function(e){if(0===e.length)return 0;let t=[...e].sort((e,t)=>e.startMs-t.startMs),n=0,r=t[0];for(let e=1;e<t.length;e++){let a=t[e];if(a.startMs<=r.endMs){r.endMs=Math.max(r.endMs,a.endMs);continue}n+=r.endMs-r.startMs,r=a}return n+(r.endMs-r.startMs)}(S):M&&(v||E)?f=new Date((v||E).ts).getTime()-new Date(M).getTime():M&&F&&(f=new Date(F.ts).getTime()-new Date(M).getTime()),"waiting"===b||"pending"===b){let e=F?.ts||M;if(e){let t=await (0,r.getConfig)();Date.now()-new Date(e).getTime()>t.staleThresholdMs&&(c=!0)}}return"pending"===b&&I.length>0&&!I.some(e=>"requested"===e.status)&&(c=!0),{runId:D.runId||n.default.basename(e),processId:D.processId||h?.processId||"unknown",status:b,createdAt:M,updatedAt:F?.ts||M,completedAt:(v||E)?.ts,tasks:I,events:g,totalTasks:I.length,completedTasks:k,failedTasks:A,duration:f,failedStep:C,failureError:a,failureMessage:s,breakpointQuestion:i,isStale:c,waitingKind:d,_journalFileCount:y.fileCount}}async function g(e,t){let r,a=n.default.join(e,"tasks",t);if(!await d(a))return null;let[s,i,l,p,c,m]=await Promise.allSettled([u(n.default.join(a,"task.json"),null),u(n.default.join(a,"input.json"),void 0),u(n.default.join(a,"result.json"),void 0),f(n.default.join(a,"stdout.log")),f(n.default.join(a,"stderr.log")),h(n.default.join(e,"journal"))]),y="fulfilled"===s.status?s.value:null,g="fulfilled"===i.status?i.value:void 0,w="fulfilled"===l.status?l.value:void 0,v="fulfilled"===p.status?p.value:void 0,E="fulfilled"===c.status?c.value:void 0,D="fulfilled"===m.status?m.value:[],T=w?.startedAt,j=w?.finishedAt,I=D.find(e=>"EFFECT_REQUESTED"===e.type&&e.payload.effectId===t),k=D.find(e=>"EFFECT_RESOLVED"===e.type&&e.payload.effectId===t),A=I?.ts||"",R=k?.ts,C=o({startedAt:T,finishedAt:j,requestedAt:A,resolvedAt:R}),b=g??y?.inputs,M=y?.kind||"agent";"breakpoint"===M&&b&&(r={question:b.question||"Approval required",title:b.title||y?.title||"Breakpoint",options:Array.isArray(b.options)?b.options:void 0,context:b.context});let F=k?.payload,S=w?"error"===w.status:F?.status==="error";return{effectId:t,kind:M,title:y?.title||t,label:y?.title||t,status:k?S?"error":"resolved":"requested",invocationKey:y?.invocationKey||"",stepId:y?.stepId||"",taskId:y?.taskId||"",requestedAt:A,resolvedAt:R,startedAt:T,finishedAt:j,duration:C,input:b,result:w??void 0,stdout:v,stderr:E,taskDef:y??void 0,breakpoint:r,breakpointQuestion:r?.question}}async function w(e){let a,s,i,l,o=n.default.join(e,"journal"),f=0,h="pending",m=0,y=0,g="",w=new Set,v=new Set,E=new Set,D=[];if(await d(o)){let e=(await t.promises.readdir(o)).filter(e=>e.endsWith(".json")).sort();f=e.length;let r=e.map(e=>()=>u(n.default.join(o,e),null)),a=await p(r);for(let t=0;t<e.length;t++){let n=a[t],r="fulfilled"===n.status?n.value:null;if(!r)continue;let s=c(r,e[t]);if(s){if(g=s.ts,"EFFECT_REQUESTED"===s.type){m++;let e=s.payload,t=e.effectId,n=e.kind||"agent";D.push({effectId:t,kind:n}),"breakpoint"===e.kind&&(w.add(t),E.add(t))}if("EFFECT_RESOLVED"===s.type){y++;let e=s.payload;v.add(e.effectId)}"RUN_COMPLETED"===s.type&&(h="completed"),"RUN_FAILED"===s.type&&(h="failed")}}"pending"===h&&m>0&&(h="waiting")}let T=0;if(w.size>0){let t=[...w].filter(e=>!v.has(e));if(t.length>0){let r=await Promise.all(t.map(t=>u(n.default.join(e,"tasks",t,"result.json"),null)));for(let e=0;e<t.length;e++)r[e]&&"ok"===r[e].status?v.add(t[e]):T++}}if("waiting"===h&&E.size>0){let t=[...E].filter(e=>!v.has(e));if(t.length>0){s=t[0];let r=t.map(t=>()=>u(n.default.join(e,"tasks",t,"task.json"),null)),i=await p(r);for(let e=0;e<t.length;e++){let n=i[e],r="fulfilled"===n.status?n.value:null;if(r){let n=r.inputs;if(n&&"string"==typeof n.question){a=n.question,s=t[e];break}}}}}if("waiting"===h){let e=D.filter(e=>!v.has(e.effectId)),t=e[e.length-1];t&&(i="breakpoint"===t.kind?"breakpoint":"task")}if(("waiting"===h||"pending"===h)&&g){let e=await (0,r.getConfig)();Date.now()-new Date(g).getTime()>e.staleThresholdMs&&(l=!0)}return"waiting"===h&&m>0&&y>=m&&(l=!0),{runId:n.default.basename(e),latestSeq:f,status:h,taskCount:m,completedTasks:y,updatedAt:g,pendingBreakpoints:T,breakpointQuestion:a,breakpointEffectId:s,isStale:l,waitingKind:i}}e.s(["getRunDigest",0,w,"parseJournalDir",0,h,"parseRunDir",0,y,"parseTaskDetail",0,g])},75619,e=>{"use strict";var t=e.i(22734),n=e.i(14747),r=e.i(37315);async function a(e){let a=[];async function s(i,l){try{if(0===e.depth)return(await t.promises.readdir(i,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>n.default.join(i,e.name));let r=n.default.join(i,".a5c","runs");try{(await t.promises.stat(r)).isDirectory()&&a.push(r)}catch{}if(l<e.depth)for(let e of(await t.promises.readdir(i,{withFileTypes:!0})))e.isDirectory()&&!e.name.startsWith(".")&&"node_modules"!==e.name&&await s(n.default.join(i,e.name),l+1)}catch(e){(0,r.isNotFoundError)(e)||console.warn(`[config] Cannot scan directory ${i} (depth=${l}):`,e)}}if(0===e.depth)try{return(await t.promises.readdir(e.path,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(t=>n.default.join(e.path,t.name))}catch(t){return console.warn(`[config] Cannot list runs in direct source ${e.path}:`,t),[]}return await s(e.path,0),a}let s=[],i=0;async function l(){let e=Date.now();if(s.length>0&&e-i<1e4)return s;let l=await (0,r.getConfig)(),o=[];for(let e of l.sources)if(0===e.depth){let a=e.label||n.default.basename(e.path);try{for(let s of(await t.promises.readdir(e.path,{withFileTypes:!0})))if(s.isDirectory()){let i=a;try{let r=n.default.join(e.path,s.name,"run.json"),a=await t.promises.readFile(r,"utf-8"),l=JSON.parse(a);l.projectName&&(i=l.projectName)}catch(t){(0,r.isNotFoundError)(t)||console.warn(`[config] Failed to read run.json in ${n.default.join(e.path,s.name)} — using fallback project name:`,t)}o.push({runDir:n.default.join(e.path,s.name),source:e,projectName:i,projectPath:e.path})}}catch(t){console.warn(`[config] Source directory not accessible ${e.path}:`,t)}}else for(let r of(await a(e))){let{projectName:a,projectPath:s}=function(e){let t=n.default.dirname(e),r=n.default.dirname(t);return{projectName:n.default.basename(r),projectPath:r}}(r);try{for(let i of(await t.promises.readdir(r,{withFileTypes:!0})))i.isDirectory()&&o.push({runDir:n.default.join(r,i.name),source:e,projectName:a,projectPath:s})}catch(e){console.warn(`[config] Cannot read runs directory ${r}:`,e)}}let d=new Map;for(let e of o){let r=n.default.basename(e.runDir);if(d.has(r)){let a=d.get(r);!await t.promises.access(n.default.join(a.runDir,"run.json")).then(()=>!0,()=>!1)&&await t.promises.access(n.default.join(e.runDir,"run.json")).then(()=>!0,()=>!1)&&d.set(r,e)}else d.set(r,e)}let u=Array.from(d.values());return s=u,i=Date.now(),u}async function o(){let e=await (0,r.getConfig)(),n=[];for(let r of e.sources)if(0===r.depth)try{await t.promises.access(r.path),n.push(r.path)}catch(e){console.warn(`[config] Watch source path not accessible ${r.path}:`,e)}else{let e=await a(r);n.push(...e)}return n}e.s(["discoverAllRunDirs",0,l,"discoverAllRunsParentDirs",0,o,"invalidateDiscoveryCache",0,function(){s=[],i=0}])}];
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=packages_observer-dashboard_src_lib_0rqgpk0._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/observer-dashboard/src/lib/config-loader.ts","../../../../../packages/observer-dashboard/src/lib/parser.ts","../../../../../packages/observer-dashboard/src/lib/source-discovery.ts"],"sourcesContent":["import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\n/** Return true when err represents a \"file/directory not found\" filesystem error. */\nexport function isNotFoundError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const code = (err as NodeJS.ErrnoException).code;\n return code === \"ENOENT\" || code === \"ENOTDIR\" || err.message.includes(\"ENOENT\");\n}\n\nexport interface WatchSource {\n path: string;\n depth: number; // how many levels deep to search for .a5c/runs/\n label?: string;\n}\n\nexport interface ObserverConfig {\n sources: WatchSource[];\n port: number;\n pollInterval: number;\n theme: \"dark\" | \"light\";\n staleThresholdMs: number;\n recentCompletionWindowMs: number;\n retentionDays: number;\n hiddenProjects: string[];\n}\n\n// Default registry path\nconst REGISTRY_PATH =\n process.env.OBSERVER_REGISTRY ||\n path.join(os.homedir(), \".a5c\", \"observer.json\");\n\nlet cachedConfig: ObserverConfig | null = null;\nlet cacheTime = 0;\nconst CACHE_TTL = 10000; // 10s\n\n// Invalidate the config cache (called after POST /api/config writes new values)\nexport function invalidateConfigCache(): void {\n cachedConfig = null;\n cacheTime = 0;\n}\n\n// Write config to the registry file (~/.a5c/observer.json)\nexport async function writeConfig(data: {\n sources: WatchSource[];\n pollInterval?: number;\n theme?: string;\n staleThresholdMs?: number;\n recentCompletionWindowMs?: number;\n retentionDays?: number;\n hiddenProjects?: string[];\n}): Promise<void> {\n const dir = path.dirname(REGISTRY_PATH);\n await fs.mkdir(dir, { recursive: true });\n\n // Read existing file to preserve any extra fields\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(REGISTRY_PATH, \"utf-8\");\n existing = JSON.parse(content);\n } catch (err) {\n // Expected when writing config for the first time; warn if the file exists but is unreadable\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to read existing config at ${REGISTRY_PATH} before merge:`, err);\n }\n }\n\n const merged = {\n ...existing,\n sources: data.sources,\n ...(data.pollInterval !== undefined ? { pollInterval: data.pollInterval } : {}),\n ...(data.theme !== undefined ? { theme: data.theme } : {}),\n ...(data.staleThresholdMs !== undefined ? { staleThresholdMs: data.staleThresholdMs } : {}),\n ...(data.recentCompletionWindowMs !== undefined ? { recentCompletionWindowMs: data.recentCompletionWindowMs } : {}),\n ...(data.retentionDays !== undefined ? { retentionDays: data.retentionDays } : {}),\n ...(data.hiddenProjects !== undefined ? { hiddenProjects: data.hiddenProjects } : {}),\n };\n\n await fs.writeFile(REGISTRY_PATH, JSON.stringify(merged, null, 2) + \"\\n\", \"utf-8\");\n}\n\ninterface RegistryData {\n sources: WatchSource[];\n pollInterval?: number;\n theme?: \"dark\" | \"light\";\n staleThresholdMs?: number;\n recentCompletionWindowMs?: number;\n retentionDays?: number;\n hiddenProjects?: string[];\n}\n\nasync function loadRegistry(): Promise<RegistryData> {\n try {\n const content = await fs.readFile(REGISTRY_PATH, \"utf-8\");\n const parsed = JSON.parse(content);\n const sources = Array.isArray(parsed.sources)\n ? parsed.sources.map((s: Record<string, unknown>) => ({\n path: String(s.path || \"\"),\n depth: typeof s.depth === \"number\" ? s.depth : 2,\n label: s.label ? String(s.label) : undefined,\n }))\n : [];\n return {\n sources,\n pollInterval: typeof parsed.pollInterval === \"number\" ? parsed.pollInterval : undefined,\n theme: parsed.theme === \"dark\" || parsed.theme === \"light\" ? parsed.theme : undefined,\n staleThresholdMs: typeof parsed.staleThresholdMs === \"number\" ? parsed.staleThresholdMs : undefined,\n recentCompletionWindowMs: typeof parsed.recentCompletionWindowMs === \"number\" ? parsed.recentCompletionWindowMs : undefined,\n retentionDays: typeof parsed.retentionDays === \"number\" ? parsed.retentionDays : undefined,\n hiddenProjects: Array.isArray(parsed.hiddenProjects) ? parsed.hiddenProjects.filter((s: unknown) => typeof s === \"string\") : undefined,\n };\n } catch (err) {\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to load registry from ${REGISTRY_PATH} — using defaults:`, err);\n }\n return { sources: [] };\n }\n}\n\nfunction getDefaultSources(): WatchSource[] {\n const sources: WatchSource[] = [];\n\n // CLI flag via OBSERVER_WATCH_DIR (set by src/cli.ts — defaults to user's cwd)\n if (process.env.OBSERVER_WATCH_DIR) {\n sources.push({ path: process.env.OBSERVER_WATCH_DIR, depth: 3, label: \"cli\" });\n }\n\n // WATCH_DIR env (backwards-compatible single dir)\n if (process.env.WATCH_DIR) {\n sources.push({ path: process.env.WATCH_DIR, depth: 0, label: \"env\" });\n }\n\n // WATCH_DIRS env (comma-separated)\n if (process.env.WATCH_DIRS) {\n for (const dir of process.env.WATCH_DIRS.split(\",\")) {\n const trimmed = dir.trim();\n if (trimmed) sources.push({ path: trimmed, depth: 2 });\n }\n }\n\n // Default: parent of cwd — users typically run from inside a project dir\n // but want to observe ALL sibling projects in the parent folder\n if (sources.length === 0) {\n sources.push({\n path: path.resolve(process.cwd(), \"..\"),\n depth: 3,\n label: \"parent\",\n });\n }\n\n return sources;\n}\n\nexport async function getConfig(): Promise<ObserverConfig> {\n const now = Date.now();\n if (cachedConfig && now - cacheTime < CACHE_TTL) {\n return cachedConfig;\n }\n\n const registry = await loadRegistry();\n const defaultSources = getDefaultSources();\n\n // Merge: registry sources take priority, defaults as fallback\n // Deduplicate sources by normalized path to prevent duplicate discovery\n const rawSources = registry.sources.length > 0 ? registry.sources : defaultSources;\n const seen = new Set<string>();\n const sources = rawSources.filter((s) => {\n const normalized = path.resolve(s.path);\n if (seen.has(normalized)) return false;\n seen.add(normalized);\n return true;\n });\n\n // Priority: registry file > env vars > defaults\n const envPollInterval = process.env.OBSERVER_POLL_INTERVAL || process.env.POLL_INTERVAL;\n const envTheme = process.env.OBSERVER_DEFAULT_THEME || process.env.THEME;\n const envStaleThreshold = process.env.OBSERVER_STALE_THRESHOLD_MS;\n const envRecentWindow = process.env.OBSERVER_RECENT_WINDOW_MS;\n const envRetentionDays = process.env.OBSERVER_RETENTION_DAYS;\n\n cachedConfig = {\n sources,\n port: parseInt(process.env.OBSERVER_PORT || process.env.PORT || \"4800\", 10),\n pollInterval: registry.pollInterval ?? (envPollInterval ? parseInt(envPollInterval, 10) : 2000),\n theme: registry.theme ?? ((envTheme === \"dark\" || envTheme === \"light\" ? envTheme : \"dark\") as \"dark\" | \"light\"),\n staleThresholdMs: registry.staleThresholdMs ?? (envStaleThreshold ? parseInt(envStaleThreshold, 10) : 3600000),\n recentCompletionWindowMs: registry.recentCompletionWindowMs ?? (envRecentWindow ? parseInt(envRecentWindow, 10) : 14400000),\n retentionDays: registry.retentionDays ?? (envRetentionDays ? parseInt(envRetentionDays, 10) : 30),\n hiddenProjects: registry.hiddenProjects ?? [],\n };\n cacheTime = now;\n\n return cachedConfig;\n}\n","import { promises as fs } from \"fs\";\r\nimport path from \"path\";\r\n\r\n/** Return true when err represents a \"file/directory not found\" filesystem error. */\r\nfunction isNotFoundError(err: unknown): boolean {\r\n if (!(err instanceof Error)) return false;\r\n const code = (err as NodeJS.ErrnoException).code;\r\n return code === \"ENOENT\" || code === \"ENOTDIR\" || err.message.includes(\"ENOENT\");\r\n}\r\n\r\nimport type {\n Run,\n RunStatus,\n JournalEvent,\n TaskEffect,\r\n TaskDetail,\r\n TaskKind,\r\n RunDigest,\r\n EffectRequestedPayload,\r\n EffectResolvedPayload,\r\n RunCreatedPayload,\r\n} from \"@/types\";\nimport { getConfig } from \"@/lib/config-loader\";\n\nfunction parseTimestampMs(value: string | undefined): number | null {\n if (!value) return null;\n const ms = new Date(value).getTime();\n return Number.isFinite(ms) ? ms : null;\n}\n\nfunction normalizeInterval(startMs: number | null, endMs: number | null): { startMs: number; endMs: number } | null {\n if (startMs == null || endMs == null) return null;\n return {\n startMs,\n endMs: Math.max(endMs, startMs),\n };\n}\n\nfunction getTaskActiveWindow(task: {\n startedAt?: string;\n finishedAt?: string;\n requestedAt?: string;\n resolvedAt?: string;\n}): { startMs: number; endMs: number } | null {\n const explicitWindow = normalizeInterval(\n parseTimestampMs(task.startedAt),\n parseTimestampMs(task.finishedAt)\n );\n if (explicitWindow) return explicitWindow;\n\n return normalizeInterval(\n parseTimestampMs(task.requestedAt),\n parseTimestampMs(task.resolvedAt)\n );\n}\n\nfunction getTaskActiveDuration(task: {\n startedAt?: string;\n finishedAt?: string;\n requestedAt?: string;\n resolvedAt?: string;\n}): number | undefined {\n const window = getTaskActiveWindow(task);\n if (!window) return undefined;\n return window.endMs - window.startMs;\n}\n\nfunction getCoveredDurationMs(windows: Array<{ startMs: number; endMs: number }>): number {\n if (windows.length === 0) return 0;\n\n const sorted = [...windows].sort((a, b) => a.startMs - b.startMs);\n let covered = 0;\n let current = sorted[0];\n\n for (let i = 1; i < sorted.length; i++) {\n const next = sorted[i];\n if (next.startMs <= current.endMs) {\n current.endMs = Math.max(current.endMs, next.endMs);\n continue;\n }\n covered += current.endMs - current.startMs;\n current = next;\n }\n\n covered += current.endMs - current.startMs;\n return covered;\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\r\n } catch (err) {\r\n // ENOENT is expected for non-existent paths; warn on permission or other errors\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Unexpected error checking existence of ${filePath}:`, err);\r\n }\r\n return false;\r\n }\r\n}\r\n\r\nasync function readJsonSafe<T>(filePath: string, fallback: T | null | undefined): Promise<T | null | undefined> {\r\n try {\r\n const content = await fs.readFile(filePath, \"utf-8\");\r\n return JSON.parse(content) as T;\r\n } catch (err) {\r\n // ENOENT is expected for optional files; warn on parse errors or permission issues\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Failed to read/parse JSON from ${filePath}:`, err);\r\n }\r\n return fallback;\r\n }\r\n}\r\n\r\nasync function readTextSafe(filePath: string): Promise<string | undefined> {\r\n try {\r\n return await fs.readFile(filePath, \"utf-8\");\r\n } catch (err) {\r\n // ENOENT is expected for optional log files; warn on permission or other errors\r\n if (!isNotFoundError(err)) {\r\n console.warn(`[parser] Failed to read text file ${filePath}:`, err);\r\n }\r\n return undefined;\r\n }\r\n}\r\n\r\n/** Maximum concurrent filesystem operations to prevent file descriptor exhaustion. */\r\nconst BATCH_CONCURRENCY_LIMIT = 50;\r\n\r\n/**\r\n * Execute an array of async factory functions with a concurrency limit.\r\n * Returns results in the same order as the input, using Promise.allSettled\r\n * semantics so that individual failures don't crash the batch.\r\n */\r\nasync function batchAllSettled<T>(\r\n factories: Array<() => Promise<T>>,\r\n limit: number = BATCH_CONCURRENCY_LIMIT\r\n): Promise<PromiseSettledResult<T>[]> {\r\n const results: PromiseSettledResult<T>[] = new Array(factories.length);\r\n let nextIndex = 0;\r\n\r\n async function worker() {\r\n while (nextIndex < factories.length) {\r\n const idx = nextIndex++;\r\n try {\r\n const value = await factories[idx]();\r\n results[idx] = { status: \"fulfilled\", value };\r\n } catch (reason) {\r\n results[idx] = { status: \"rejected\", reason };\r\n }\r\n }\r\n }\r\n\r\n const workerCount = Math.min(limit, factories.length);\r\n const workers: Promise<void>[] = [];\r\n for (let i = 0; i < workerCount; i++) {\r\n workers.push(worker());\r\n }\r\n await Promise.all(workers);\r\n return results;\r\n}\r\n\r\n// Normalize raw journal entry (which uses `data` and `recordedAt`) into our JournalEvent type\r\nfunction normalizeJournalEvent(raw: Record<string, unknown>, filename: string): JournalEvent | null {\r\n if (!raw || !raw.type) return null;\r\n\r\n // Parse seq and id from filename: \"000001.ULID.json\"\r\n const parts = filename.replace(/\\.json$/, \"\").split(\".\");\r\n const seq = parseInt(parts[0], 10) || 0;\r\n const id = parts[1] || \"\";\r\n\r\n return {\r\n seq,\r\n id,\r\n ts: (raw.recordedAt as string) || (raw.ts as string) || \"\",\r\n type: raw.type as JournalEvent[\"type\"],\r\n payload: (raw.data as Record<string, unknown>) || (raw.payload as Record<string, unknown>) || {},\r\n };\r\n}\r\n\r\n/** Result of an incremental journal parse. */\r\nexport interface IncrementalJournalResult {\r\n events: JournalEvent[];\r\n /** Number of JSON files in the journal directory after this parse. */\r\n fileCount: number;\r\n}\r\n\r\nexport async function parseJournalDir(\r\n journalPath: string\r\n): Promise<JournalEvent[]> {\r\n const result = await parseJournalDirIncremental(journalPath);\r\n return result.events;\r\n}\r\n\r\n/**\r\n * Incrementally parse a journal directory.\r\n *\r\n * When `previousEvents` and `previousFileCount` are supplied the function\r\n * skips files that were already parsed in a previous call. If the\r\n * directory now has *fewer* files than `previousFileCount` (truncation /\r\n * rotation) the journal is re-read from scratch.\r\n *\r\n * @param journalPath Path to the journal directory.\r\n * @param previousEvents Events returned by a prior call (used as base for merge).\r\n * @param previousFileCount Number of JSON files that existed during the prior call.\r\n * @returns Merged events array (sorted by seq) and the current file count.\r\n */\r\nexport async function parseJournalDirIncremental(\r\n journalPath: string,\r\n previousEvents?: JournalEvent[],\r\n previousFileCount?: number\r\n): Promise<IncrementalJournalResult> {\r\n if (!(await fileExists(journalPath))) return { events: [], fileCount: 0 };\r\n\r\n const files = await fs.readdir(journalPath);\r\n const jsonFiles = files.filter((f) => f.endsWith(\".json\")).sort();\r\n const currentFileCount = jsonFiles.length;\r\n\r\n // Determine whether we can do an incremental read.\r\n // Incremental is possible when we have cached state AND the file count\r\n // has not shrunk (truncation / rotation guard).\r\n const canIncremental =\r\n previousEvents !== undefined &&\r\n previousFileCount !== undefined &&\r\n previousFileCount >= 0 &&\r\n currentFileCount >= previousFileCount;\r\n\r\n if (canIncremental) {\r\n const newFilesStartIdx = previousFileCount!;\r\n\r\n // No new files — return the previous result as-is.\r\n if (newFilesStartIdx >= currentFileCount) {\r\n return { events: previousEvents!, fileCount: currentFileCount };\r\n }\r\n\r\n const newFiles = jsonFiles.slice(newFilesStartIdx);\r\n\r\n // Batch-read only the new files\r\n const readFactories = newFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n const newEvents: JournalEvent[] = [];\r\n for (let i = 0; i < newFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (raw) {\r\n const event = normalizeJournalEvent(raw, newFiles[i]);\r\n if (event) newEvents.push(event);\r\n }\r\n }\r\n\r\n // Merge: previousEvents is already sorted; new events are appended and\r\n // the full array is re-sorted to guarantee correctness.\r\n const merged = [...previousEvents!, ...newEvents].sort((a, b) => a.seq - b.seq);\r\n return { events: merged, fileCount: currentFileCount };\r\n }\r\n\r\n // Full re-read (first call, or truncation detected).\r\n const readFactories = jsonFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n const events: JournalEvent[] = [];\r\n for (let i = 0; i < jsonFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (raw) {\r\n const event = normalizeJournalEvent(raw, jsonFiles[i]);\r\n if (event) events.push(event);\r\n }\r\n }\r\n\r\n return { events: events.sort((a, b) => a.seq - b.seq), fileCount: currentFileCount };\r\n}\r\n\r\n/** Options for incremental run parsing. */\r\nexport interface IncrementalRunOptions {\r\n previousEvents?: JournalEvent[];\r\n previousFileCount?: number;\r\n}\r\n\r\n/** Extended Run result that includes the journal file count for caching. */\r\nexport interface ParseRunResult extends Run {\r\n /** Number of journal files parsed — used by the cache layer for incremental reads. */\r\n _journalFileCount: number;\r\n}\r\n\r\nexport async function parseRunDir(\r\n runPath: string,\r\n incremental?: IncrementalRunOptions\r\n): Promise<ParseRunResult> {\r\n const runJson = await readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"run.json\"),\r\n {}\r\n );\r\n\r\n const journalResult = await parseJournalDirIncremental(\r\n path.join(runPath, \"journal\"),\r\n incremental?.previousEvents,\r\n incremental?.previousFileCount\r\n );\r\n const events = journalResult.events;\r\n\r\n // Extract run info from events\r\n const runCreated = events.find((e) => e.type === \"RUN_CREATED\");\r\n const runCompleted = events.find((e) => e.type === \"RUN_COMPLETED\");\r\n const runFailed = events.find((e) => e.type === \"RUN_FAILED\");\r\n\r\n const createdPayload = (runCreated?.payload ||\r\n {}) as unknown as RunCreatedPayload;\r\n\r\n // Build task map from events — first pass: collect all requested/resolved info\r\n const taskMap = new Map<string, TaskEffect>();\r\n const requestedPayloads: EffectRequestedPayload[] = [];\r\n\r\n for (const event of events) {\r\n if (event.type === \"EFFECT_REQUESTED\") {\r\n const p = event.payload as unknown as EffectRequestedPayload;\r\n requestedPayloads.push(p);\r\n taskMap.set(p.effectId, {\r\n effectId: p.effectId,\r\n kind: p.kind,\r\n title: p.label || p.taskId,\r\n label: p.label || p.taskId,\r\n status: \"requested\",\r\n invocationKey: p.invocationKey,\r\n stepId: p.stepId,\r\n taskId: p.taskId,\r\n requestedAt: event.ts,\r\n });\r\n }\r\n\r\n if (event.type === \"EFFECT_RESOLVED\") {\r\n const p = event.payload as unknown as EffectResolvedPayload;\r\n const task = taskMap.get(p.effectId);\r\n if (task) {\n task.status = p.status === \"ok\" ? \"resolved\" : \"error\";\n task.resolvedAt = event.ts;\n task.startedAt = p.startedAt;\n task.finishedAt = p.finishedAt;\n task.duration = getTaskActiveDuration({\n startedAt: p.startedAt,\n finishedAt: p.finishedAt,\n requestedAt: task.requestedAt,\n resolvedAt: event.ts,\n });\n if (p.error) {\n task.error = {\n name: p.error.name,\n message: p.error.message,\r\n stack: p.error.stack,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Batch-read all task.json files in parallel for EFFECT_REQUESTED tasks\r\n if (requestedPayloads.length > 0) {\r\n const taskDefFactories = requestedPayloads.map(\r\n (p) => () =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", p.effectId, \"task.json\"),\r\n null\r\n )\r\n );\r\n const taskDefResults = await batchAllSettled(taskDefFactories);\r\n\r\n for (let i = 0; i < requestedPayloads.length; i++) {\r\n const p = requestedPayloads[i];\r\n const result = taskDefResults[i];\r\n const taskDef = result.status === \"fulfilled\" ? result.value : null;\r\n if (taskDef) {\r\n const task = taskMap.get(p.effectId)!;\r\n task.title = (taskDef.title as string) || task.title;\r\n if (taskDef.agent && typeof taskDef.agent === \"object\") {\r\n const agentDef = taskDef.agent as Record<string, unknown>;\r\n task.agent = {\r\n name: (agentDef.name as string) || \"unknown\",\r\n prompt: agentDef.prompt as NonNullable<TaskEffect[\"agent\"]>[\"prompt\"],\r\n };\r\n }\r\n // Extract breakpoint question from inputs for breakpoint tasks\r\n if (p.kind === \"breakpoint\") {\r\n const inputs = taskDef.inputs as Record<string, unknown> | undefined;\r\n if (inputs && typeof inputs.question === \"string\") {\r\n task.breakpointQuestion = inputs.question;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n const tasks = Array.from(taskMap.values());\r\n const completedTasks = tasks.filter((t) => t.status === \"resolved\").length;\r\n const failedTasks = tasks.filter((t) => t.status === \"error\").length;\r\n\r\n // Task 1.2: Extract failed step name from the first task that resolved with error\r\n const firstFailedTask = tasks.find((t) => t.status === \"error\");\r\n const failedStep = firstFailedTask\r\n ? firstFailedTask.title || firstFailedTask.label || firstFailedTask.stepId\r\n : undefined;\r\n\r\n // Extract failure details from RUN_FAILED event or last failed EFFECT_RESOLVED\r\n let failureError: string | undefined;\r\n let failureMessage: string | undefined;\r\n\r\n if (runFailed) {\r\n const failPayload = runFailed.payload as Record<string, unknown>;\r\n const runError = failPayload.error as { name?: string; message?: string; stack?: string } | undefined;\r\n if (runError) {\r\n failureError = runError.name || \"Error\";\r\n failureMessage = runError.message || runError.stack || undefined;\r\n }\r\n }\r\n\r\n // If we still don't have a message, look at the last EFFECT_RESOLVED with error status\r\n if (!failureMessage) {\r\n const lastFailedEffect = [...events]\r\n .reverse()\r\n .find((e) => e.type === \"EFFECT_RESOLVED\" && (e.payload as Record<string, unknown>).status === \"error\");\r\n if (lastFailedEffect) {\r\n const effectPayload = lastFailedEffect.payload as Record<string, unknown>;\r\n const effectError = effectPayload.error as { name?: string; message?: string; stack?: string } | undefined;\r\n if (effectError) {\r\n failureError = failureError || effectError.name || \"Error\";\r\n failureMessage = effectError.message || effectError.stack || undefined;\r\n }\r\n }\r\n }\r\n\r\n let status: RunStatus = \"pending\";\r\n if (runCompleted) status = \"completed\";\r\n else if (runFailed) status = \"failed\";\r\n else if (tasks.some((t) => t.status === \"requested\")) status = \"waiting\";\r\n\r\n // Task 1.3: Extract breakpoint question from pending breakpoint tasks\r\n let breakpointQuestion: string | undefined;\r\n if (status === \"waiting\") {\r\n const pendingBreakpoint = tasks.find(\r\n (t) => t.kind === \"breakpoint\" && t.status === \"requested\"\r\n );\r\n if (pendingBreakpoint?.breakpointQuestion) {\r\n breakpointQuestion = pendingBreakpoint.breakpointQuestion;\r\n }\r\n }\r\n\r\n // Determine waitingKind: check the last requested (pending) task\r\n let waitingKind: 'breakpoint' | 'task' | undefined;\r\n if (status === \"waiting\") {\r\n const requestedTasks = tasks.filter((t) => t.status === \"requested\");\r\n const lastRequested = requestedTasks[requestedTasks.length - 1];\r\n if (lastRequested) {\r\n waitingKind = lastRequested.kind === \"breakpoint\" ? \"breakpoint\" : \"task\";\r\n }\r\n }\r\n\r\n const createdAt = runCreated?.ts || \"\";\n const lastEvent = events[events.length - 1];\n\n let duration: number | undefined;\n const taskWindows = tasks\n .map((task) => getTaskActiveWindow(task))\n .filter((window): window is { startMs: number; endMs: number } => window !== null);\n if (taskWindows.length > 0) {\n duration = getCoveredDurationMs(taskWindows);\n } else if (createdAt && (runCompleted || runFailed)) {\n const endTs = (runCompleted || runFailed)!.ts;\n duration = new Date(endTs).getTime() - new Date(createdAt).getTime();\n } else if (createdAt && lastEvent) {\n duration =\n new Date(lastEvent.ts).getTime() - new Date(createdAt).getTime();\n }\n\r\n // Detect staleness for waiting or pending runs\r\n let isStale: boolean | undefined;\r\n if (status === \"waiting\" || status === \"pending\") {\r\n const updatedAtTs = lastEvent?.ts || createdAt;\r\n if (updatedAtTs) {\r\n const config = await getConfig();\r\n const timeSinceUpdate = Date.now() - new Date(updatedAtTs).getTime();\r\n if (timeSinceUpdate > config.staleThresholdMs) {\r\n isStale = true;\r\n }\r\n }\r\n }\r\n\r\n // Detect orphaned runs: all tasks resolved but no terminal event\r\n // (process likely crashed before writing RUN_COMPLETED)\r\n if (status === \"pending\" && tasks.length > 0 && !tasks.some((t) => t.status === \"requested\")) {\r\n isStale = true;\r\n }\r\n\r\n return {\r\n runId: createdPayload.runId || path.basename(runPath),\r\n processId:\r\n createdPayload.processId ||\r\n (runJson?.processId as string) ||\r\n \"unknown\",\r\n status,\r\n createdAt,\r\n updatedAt: lastEvent?.ts || createdAt,\r\n completedAt: (runCompleted || runFailed)?.ts,\r\n tasks,\r\n events,\r\n totalTasks: tasks.length,\r\n completedTasks,\r\n failedTasks,\r\n duration,\r\n failedStep,\r\n failureError,\r\n failureMessage,\r\n breakpointQuestion,\r\n isStale,\r\n waitingKind,\r\n _journalFileCount: journalResult.fileCount,\r\n };\r\n}\r\n\r\nexport async function parseTaskDetail(\r\n runPath: string,\r\n effectId: string\r\n): Promise<TaskDetail | null> {\r\n const taskDir = path.join(runPath, \"tasks\", effectId);\r\n if (!(await fileExists(taskDir))) return null;\r\n\r\n // Read all 5 task files + journal in parallel with Promise.allSettled\r\n const [\r\n taskDefResult,\r\n inputResult,\r\n resultResult,\r\n stdoutResult,\r\n stderrResult,\r\n journalEventsResult,\r\n ] = await Promise.allSettled([\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"task.json\"), null),\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"input.json\"), undefined),\r\n readJsonSafe<Record<string, unknown>>(path.join(taskDir, \"result.json\"), undefined),\r\n readTextSafe(path.join(taskDir, \"stdout.log\")),\r\n readTextSafe(path.join(taskDir, \"stderr.log\")),\r\n parseJournalDir(path.join(runPath, \"journal\")),\r\n ]);\r\n\r\n const taskDef = taskDefResult.status === \"fulfilled\" ? taskDefResult.value : null;\r\n const input = inputResult.status === \"fulfilled\" ? inputResult.value : undefined;\r\n const result = resultResult.status === \"fulfilled\" ? resultResult.value : undefined;\r\n const stdout = stdoutResult.status === \"fulfilled\" ? stdoutResult.value : undefined;\r\n const stderr = stderrResult.status === \"fulfilled\" ? stderrResult.value : undefined;\r\n const journalEvents = journalEventsResult.status === \"fulfilled\" ? journalEventsResult.value : [];\r\n\r\n // Extract timing from result.json\r\n const resultStartedAt = result?.startedAt as string | undefined;\r\n const resultFinishedAt = result?.finishedAt as string | undefined;\r\n const requestedEvent = journalEvents.find(\r\n (e) => e.type === \"EFFECT_REQUESTED\" && (e.payload as Record<string, unknown>).effectId === effectId\r\n );\r\n const resolvedEvent = journalEvents.find(\r\n (e) => e.type === \"EFFECT_RESOLVED\" && (e.payload as Record<string, unknown>).effectId === effectId\r\n );\r\n\r\n const requestedAt = requestedEvent?.ts || \"\";\r\n const resolvedAt = resolvedEvent?.ts;\n\n const duration = getTaskActiveDuration({\n startedAt: resultStartedAt,\n finishedAt: resultFinishedAt,\n requestedAt,\n resolvedAt,\n });\n\r\n // Use inputs from task.json if separate input.json doesn't exist\r\n const resolvedInput = input ?? (taskDef?.inputs as Record<string, unknown> | undefined);\r\n\r\n // Extract breakpoint payload for breakpoint tasks\r\n const kind = (taskDef?.kind as TaskKind) || \"agent\";\r\n let breakpointPayload: import(\"@/types\").BreakpointPayload | undefined;\r\n if (kind === \"breakpoint\" && resolvedInput) {\r\n breakpointPayload = {\r\n question: (resolvedInput.question as string) || \"Approval required\",\r\n title: (resolvedInput.title as string) || (taskDef?.title as string) || \"Breakpoint\",\r\n options: Array.isArray(resolvedInput.options) ? (resolvedInput.options as string[]) : undefined,\r\n context: resolvedInput.context as import(\"@/types\").BreakpointPayload[\"context\"],\r\n };\r\n }\r\n\r\n // Determine error status from result or journal\r\n const resolvedPayload = resolvedEvent?.payload as Record<string, unknown> | undefined;\r\n const isError = result\r\n ? (result.status === \"error\")\r\n : (resolvedPayload?.status === \"error\");\r\n\r\n return {\r\n effectId,\r\n kind,\r\n title: (taskDef?.title as string) || effectId,\r\n label: (taskDef?.title as string) || effectId,\r\n status: resolvedEvent ? (isError ? \"error\" : \"resolved\") : \"requested\",\r\n invocationKey: (taskDef?.invocationKey as string) || \"\",\r\n stepId: (taskDef?.stepId as string) || \"\",\r\n taskId: (taskDef?.taskId as string) || \"\",\r\n requestedAt,\r\n resolvedAt,\r\n startedAt: resultStartedAt,\r\n finishedAt: resultFinishedAt,\r\n duration,\r\n input: resolvedInput,\r\n result: result ?? undefined,\r\n stdout,\r\n stderr,\r\n taskDef: taskDef ?? undefined,\r\n breakpoint: breakpointPayload,\r\n breakpointQuestion: breakpointPayload?.question,\r\n };\r\n}\r\n\r\nexport async function getRunDigest(runPath: string): Promise<RunDigest> {\r\n const journalPath = path.join(runPath, \"journal\");\r\n let latestSeq = 0;\r\n let status: RunStatus = \"pending\";\r\n let taskCount = 0;\r\n let completedTasks = 0;\r\n let updatedAt = \"\";\r\n\r\n const requestedBreakpoints = new Set<string>();\r\n const resolvedEffects = new Set<string>();\r\n const breakpointEffectIds = new Set<string>();\r\n // Track requested effects and their kinds for waitingKind determination\r\n const requestedEffects: Array<{ effectId: string; kind: string }> = [];\r\n\r\n if (await fileExists(journalPath)) {\r\n const files = await fs.readdir(journalPath);\r\n const jsonFiles = files.filter((f) => f.endsWith(\".json\")).sort();\r\n latestSeq = jsonFiles.length;\r\n\r\n // Batch-read all journal files in parallel with concurrency limit\r\n const readFactories = jsonFiles.map(\r\n (file) => () =>\r\n readJsonSafe<Record<string, unknown>>(path.join(journalPath, file), null)\r\n );\r\n const settled = await batchAllSettled(readFactories);\r\n\r\n // Process results sequentially to maintain event ordering for updatedAt\r\n for (let i = 0; i < jsonFiles.length; i++) {\r\n const result = settled[i];\r\n const raw = result.status === \"fulfilled\" ? result.value : null;\r\n if (!raw) continue;\r\n const event = normalizeJournalEvent(raw, jsonFiles[i]);\r\n if (!event) continue;\r\n updatedAt = event.ts;\r\n if (event.type === \"EFFECT_REQUESTED\") {\r\n taskCount++;\r\n const data = event.payload as Record<string, unknown>;\r\n const effectId = data.effectId as string;\r\n const kind = (data.kind as string) || \"agent\";\r\n requestedEffects.push({ effectId, kind });\r\n if (data.kind === \"breakpoint\") {\r\n requestedBreakpoints.add(effectId);\r\n breakpointEffectIds.add(effectId);\r\n }\r\n }\r\n if (event.type === \"EFFECT_RESOLVED\") {\r\n completedTasks++;\r\n const data = event.payload as Record<string, unknown>;\r\n resolvedEffects.add(data.effectId as string);\r\n }\r\n if (event.type === \"RUN_COMPLETED\") status = \"completed\";\r\n if (event.type === \"RUN_FAILED\") status = \"failed\";\r\n }\r\n\r\n if (status === \"pending\" && taskCount > 0) status = \"waiting\";\r\n }\r\n\r\n // Count pending breakpoints (requested but not yet resolved).\r\n // Also check result.json — the dashboard writes it on approve but can't\r\n // write journal events, so the journal alone may lag behind.\r\n let pendingBreakpoints = 0;\r\n if (requestedBreakpoints.size > 0) {\r\n const unresolvedBps = [...requestedBreakpoints].filter(\r\n (id) => !resolvedEffects.has(id)\r\n );\r\n if (unresolvedBps.length > 0) {\r\n const resultChecks = await Promise.all(\r\n unresolvedBps.map((id) =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", id, \"result.json\"),\r\n null\r\n )\r\n )\r\n );\r\n for (let i = 0; i < unresolvedBps.length; i++) {\r\n if (resultChecks[i] && resultChecks[i]!.status === \"ok\") {\r\n resolvedEffects.add(unresolvedBps[i]);\r\n } else {\r\n pendingBreakpoints++;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract breakpoint question and effectId from pending breakpoint tasks — batch-read all at once\r\n let breakpointQuestion: string | undefined;\r\n let breakpointEffectId: string | undefined;\r\n if (status === \"waiting\" && breakpointEffectIds.size > 0) {\r\n const pendingBpIds = [...breakpointEffectIds].filter(\r\n (id) => !resolvedEffects.has(id)\r\n );\r\n if (pendingBpIds.length > 0) {\r\n // Store the first pending breakpoint effectId regardless of question\r\n breakpointEffectId = pendingBpIds[0];\r\n\r\n const bpFactories = pendingBpIds.map(\r\n (effectId) => () =>\r\n readJsonSafe<Record<string, unknown>>(\r\n path.join(runPath, \"tasks\", effectId, \"task.json\"),\r\n null\r\n )\r\n );\r\n const bpResults = await batchAllSettled(bpFactories);\r\n\r\n // Use the first pending breakpoint question found\r\n for (let i = 0; i < pendingBpIds.length; i++) {\r\n const result = bpResults[i];\r\n const taskDef = result.status === \"fulfilled\" ? result.value : null;\r\n if (taskDef) {\r\n const inputs = taskDef.inputs as Record<string, unknown> | undefined;\r\n if (inputs && typeof inputs.question === \"string\") {\r\n breakpointQuestion = inputs.question;\r\n breakpointEffectId = pendingBpIds[i];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Determine waitingKind from the last requested (pending) effect\r\n let waitingKind: 'breakpoint' | 'task' | undefined;\r\n if (status === \"waiting\") {\r\n // Find the last requested effect that hasn't been resolved\r\n const pendingEffects = requestedEffects.filter(\r\n (e) => !resolvedEffects.has(e.effectId)\r\n );\r\n const lastPending = pendingEffects[pendingEffects.length - 1];\r\n if (lastPending) {\r\n waitingKind = lastPending.kind === \"breakpoint\" ? \"breakpoint\" : \"task\";\r\n }\r\n }\r\n\r\n // Detect staleness for waiting or pending runs\r\n let isStale: boolean | undefined;\r\n if (status === \"waiting\" || status === \"pending\") {\r\n if (updatedAt) {\r\n const config = await getConfig();\r\n const timeSinceUpdate = Date.now() - new Date(updatedAt).getTime();\r\n if (timeSinceUpdate > config.staleThresholdMs) {\r\n isStale = true;\r\n }\r\n }\r\n }\r\n\r\n // Detect orphaned runs: all effects resolved but no terminal event\r\n if (status === \"waiting\" && taskCount > 0 && completedTasks >= taskCount) {\r\n isStale = true;\r\n }\r\n\r\n return {\r\n runId: path.basename(runPath),\r\n latestSeq,\r\n status,\r\n taskCount,\r\n completedTasks,\r\n updatedAt,\r\n pendingBreakpoints,\r\n breakpointQuestion,\r\n breakpointEffectId,\r\n isStale,\r\n waitingKind,\r\n };\r\n}\r\n\r\nexport async function getRunIds(runsPath: string): Promise<string[]> {\r\n if (!(await fileExists(runsPath))) return [];\r\n const entries = await fs.readdir(runsPath, { withFileTypes: true });\r\n return entries\r\n .filter((e) => e.isDirectory())\r\n .map((e) => e.name)\r\n .sort()\r\n .reverse();\r\n}\r\n","import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport { isNotFoundError, getConfig, type WatchSource } from \"./config-loader\";\n\nexport interface DiscoveredRun {\n runDir: string;\n source: WatchSource;\n projectName: string; // e.g. \"hockey_7_shifts\", \"podcast-intel\"\n projectPath: string; // full path to the project directory\n}\n\n// Discover all .a5c/runs/ directories within a source\nasync function discoverRunsInSource(source: WatchSource): Promise<string[]> {\n const results: string[] = [];\n\n async function scan(dir: string, currentDepth: number) {\n try {\n // Check if this directory itself IS an .a5c/runs dir (depth=0 means direct path)\n if (source.depth === 0) {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(dir, e.name));\n }\n\n // Check for .a5c/runs/ at this level\n const runsPath = path.join(dir, \".a5c\", \"runs\");\n try {\n const stat = await fs.stat(runsPath);\n if (stat.isDirectory()) {\n results.push(runsPath);\n }\n } catch {\n // Expected: no .a5c/runs directory at this level — skip silently\n }\n\n // Recurse into subdirectories if within depth\n if (currentDepth < source.depth) {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !entry.name.startsWith(\".\") &&\n entry.name !== \"node_modules\"\n ) {\n await scan(path.join(dir, entry.name), currentDepth + 1);\n }\n }\n }\n } catch (err) {\n if (!isNotFoundError(err)) {\n console.warn(`[config] Cannot scan directory ${dir} (depth=${currentDepth}):`, err);\n }\n }\n }\n\n if (source.depth === 0) {\n // Direct .a5c/runs path — just return runs inside it\n try {\n const entries = await fs.readdir(source.path, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => path.join(source.path, e.name));\n } catch (err) {\n console.warn(`[config] Cannot list runs in direct source ${source.path}:`, err);\n return [];\n }\n }\n\n await scan(source.path, 0);\n return results;\n}\n\n// Extract project name from a .a5c/runs/ path\nfunction extractProjectName(runsDir: string): { projectName: string; projectPath: string } {\n // runsDir is like /path/to/project/.a5c/runs\n // projectPath is /path/to/project\n const a5cDir = path.dirname(runsDir); // .a5c\n const projectPath = path.dirname(a5cDir); // project dir\n const projectName = path.basename(projectPath);\n return { projectName, projectPath };\n}\n\n// Cache discovery results to avoid repeated filesystem scanning\nlet discoveryCache: DiscoveredRun[] = [];\nlet discoveryCacheTime = 0;\nconst DISCOVERY_CACHE_TTL = 10000; // 10s — watcher handles real-time changes\n\n// Force re-discovery on next call (called when new runs are detected by watcher)\nexport function invalidateDiscoveryCache(): void {\n discoveryCache = [];\n discoveryCacheTime = 0;\n}\n\n// Get all run directories across all sources\nexport async function discoverAllRunDirs(): Promise<DiscoveredRun[]> {\n const now = Date.now();\n if (discoveryCache.length > 0 && now - discoveryCacheTime < DISCOVERY_CACHE_TTL) {\n return discoveryCache;\n }\n\n const config = await getConfig();\n const allRuns: DiscoveredRun[] = [];\n\n for (const source of config.sources) {\n if (source.depth === 0) {\n // Direct runs directory — list subdirs as individual runs\n // Project name: prefer run.json's projectName, fall back to source label or path\n const fallbackProjectName = source.label || path.basename(source.path);\n try {\n const entries = await fs.readdir(source.path, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n // Try to read projectName from run.json for more accurate project grouping\n let projectName = fallbackProjectName;\n try {\n const runJsonPath = path.join(source.path, entry.name, \"run.json\");\n const content = await fs.readFile(runJsonPath, \"utf-8\");\n const json = JSON.parse(content);\n if (json.projectName) {\n projectName = json.projectName;\n }\n } catch (err) {\n // run.json missing is expected for new runs; warn only on parse/permission errors\n if (!isNotFoundError(err)) {\n console.warn(`[config] Failed to read run.json in ${path.join(source.path, entry.name)} — using fallback project name:`, err);\n }\n }\n allRuns.push({\n runDir: path.join(source.path, entry.name),\n source,\n projectName,\n projectPath: source.path,\n });\n }\n }\n } catch (err) {\n console.warn(`[config] Source directory not accessible ${source.path}:`, err);\n }\n } else {\n // Discover .a5c/runs/ directories within depth\n const runsDirs = await discoverRunsInSource(source);\n for (const runsDir of runsDirs) {\n const { projectName, projectPath } = extractProjectName(runsDir);\n try {\n const entries = await fs.readdir(runsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n allRuns.push({\n runDir: path.join(runsDir, entry.name),\n source,\n projectName,\n projectPath,\n });\n }\n }\n } catch (err) {\n console.warn(`[config] Cannot read runs directory ${runsDir}:`, err);\n }\n }\n }\n }\n\n // Deduplicate by runId (basename of runDir). When the same run ID appears\n // under multiple .a5c/runs/ directories (e.g. a \"ghost\" .a5c created by a\n // task execution in a subdirectory), keep the first occurrence — which is\n // the shallowest/earliest discovered and typically the one with full data\n // (run.json + journal).\n const seenRunIds = new Map<string, DiscoveredRun>();\n for (const run of allRuns) {\n const runId = path.basename(run.runDir);\n if (!seenRunIds.has(runId)) {\n seenRunIds.set(runId, run);\n } else {\n // Prefer the run directory that has a run.json (i.e. the real one)\n const existing = seenRunIds.get(runId)!;\n const existingHasRunJson = await fs.access(path.join(existing.runDir, \"run.json\")).then(() => true, () => false);\n if (!existingHasRunJson) {\n const candidateHasRunJson = await fs.access(path.join(run.runDir, \"run.json\")).then(() => true, () => false);\n if (candidateHasRunJson) {\n seenRunIds.set(runId, run);\n }\n }\n }\n }\n\n const result = Array.from(seenRunIds.values());\n discoveryCache = result;\n discoveryCacheTime = Date.now();\n return result;\n}\n\n// Discover all .a5c/runs/ parent directories (including empty ones).\n// Used by the watcher to set up watches on directories that don't have runs yet,\n// so that the very first run in a new project is detected immediately.\nexport async function discoverAllRunsParentDirs(): Promise<string[]> {\n const config = await getConfig();\n const allDirs: string[] = [];\n\n for (const source of config.sources) {\n if (source.depth === 0) {\n // Direct runs path — watch the source path itself\n try {\n await fs.access(source.path);\n allDirs.push(source.path);\n } catch (err) {\n console.warn(`[config] Watch source path not accessible ${source.path}:`, err);\n }\n } else {\n const runsDirs = await discoverRunsInSource(source);\n allDirs.push(...runsDirs);\n }\n }\n\n return allDirs;\n}\n"],"names":["isNotFoundError","err","Error","code","message","includes","REGISTRY_PATH","process","env","OBSERVER_REGISTRY","join","homedir","cachedConfig","cacheTime","CACHE_TTL","invalidateConfigCache","writeConfig","data","dir","dirname","mkdir","recursive","existing","content","readFile","JSON","parse","console","warn","merged","sources","pollInterval","undefined","theme","staleThresholdMs","recentCompletionWindowMs","retentionDays","hiddenProjects","writeFile","stringify","loadRegistry","parsed","Array","isArray","map","s","path","String","depth","label","filter","getDefaultSources","OBSERVER_WATCH_DIR","push","WATCH_DIR","WATCH_DIRS","split","trimmed","trim","length","resolve","cwd","getConfig","now","Date","registry","defaultSources","rawSources","seen","Set","normalized","has","add","envPollInterval","OBSERVER_POLL_INTERVAL","POLL_INTERVAL","envTheme","OBSERVER_DEFAULT_THEME","THEME","envStaleThreshold","OBSERVER_STALE_THRESHOLD_MS","envRecentWindow","OBSERVER_RECENT_WINDOW_MS","envRetentionDays","OBSERVER_RETENTION_DAYS","port","parseInt","OBSERVER_PORT","PORT","parseTimestampMs","value","ms","getTime","Number","isFinite","normalizeInterval","startMs","endMs","Math","max","getTaskActiveWindow","task","explicitWindow","startedAt","finishedAt","requestedAt","resolvedAt","getTaskActiveDuration","window","getCoveredDurationMs","windows","sorted","sort","a","b","covered","current","i","next","fileExists","filePath","access","readJsonSafe","fallback","readTextSafe","BATCH_CONCURRENCY_LIMIT","batchAllSettled","factories","limit","results","nextIndex","worker","idx","status","reason","workerCount","min","workers","Promise","all","normalizeJournalEvent","raw","filename","type","parts","replace","seq","id","ts","recordedAt","payload","parseJournalDir","journalPath","result","parseJournalDirIncremental","events","previousEvents","previousFileCount","fileCount","files","readdir","jsonFiles","f","endsWith","currentFileCount","canIncremental","newFilesStartIdx","newFiles","slice","readFactories","file","settled","newEvents","event","parseRunDir","runPath","incremental","runJson","journalResult","runCreated","find","e","runCompleted","runFailed","createdPayload","taskMap","Map","requestedPayloads","p","set","effectId","kind","title","taskId","invocationKey","stepId","get","duration","error","name","stack","taskDefFactories","taskDefResults","taskDef","agent","agentDef","prompt","inputs","question","breakpointQuestion","tasks","from","values","completedTasks","t","failedTasks","firstFailedTask","failedStep","failureError","failureMessage","failPayload","runError","lastFailedEffect","reverse","effectPayload","effectError","some","pendingBreakpoint","waitingKind","requestedTasks","lastRequested","createdAt","lastEvent","taskWindows","endTs","isStale","updatedAtTs","config","timeSinceUpdate","runId","basename","processId","updatedAt","completedAt","totalTasks","_journalFileCount","parseTaskDetail","taskDir","taskDefResult","inputResult","resultResult","stdoutResult","stderrResult","journalEventsResult","allSettled","input","stdout","stderr","journalEvents","resultStartedAt","resultFinishedAt","requestedEvent","resolvedEvent","resolvedInput","breakpointPayload","options","context","resolvedPayload","isError","breakpoint","getRunDigest","latestSeq","taskCount","requestedBreakpoints","resolvedEffects","breakpointEffectIds","requestedEffects","pendingBreakpoints","size","unresolvedBps","resultChecks","breakpointEffectId","pendingBpIds","bpFactories","bpResults","pendingEffects","lastPending","getRunIds","runsPath","entries","withFileTypes","isDirectory","discoverRunsInSource","source","scan","currentDepth","stat","entry","startsWith","extractProjectName","runsDir","a5cDir","projectPath","projectName","discoveryCache","discoveryCacheTime","DISCOVERY_CACHE_TTL","invalidateDiscoveryCache","discoverAllRunDirs","allRuns","fallbackProjectName","runJsonPath","json","runDir","runsDirs","seenRunIds","run","existingHasRunJson","then","candidateHasRunJson","discoverAllRunsParentDirs","allDirs"],"mappings":"uCAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAGO,SAASA,EAAgBC,CAAY,EAC1C,GAAI,CAAC,CAACA,aAAeC,KAAAA,CAAK,CAAG,OAAO,EACpC,IAAMC,EAAQF,EAA8BE,IAAI,CAChD,MAAgB,WAATA,GAA8B,YAATA,GAAsBF,EAAIG,OAAO,CAACC,QAAQ,CAAC,SACzE,CAoBA,IAAMC,EACJC,QAAQC,GAAG,CAACC,iBAAiB,EAC7B,EAAA,OAAI,CAACC,IAAI,CAAC,EAAA,OAAE,CAACC,OAAO,GAAI,OAAQ,iBAE9BC,EAAsC,KACtCC,EAAY,EAUT,eAAeG,EAAYC,CAQjC,EACC,IAAMC,EAAM,EAAA,OAAI,CAACC,OAAO,CAACb,EACzB,OAAM,EAAA,QAAE,CAACc,KAAK,CAACF,EAAK,CAAEG,WAAW,CAAK,GAGtC,IAAIC,EAAoC,CAAC,EACzC,GAAI,CACF,IAAMC,EAAU,MAAM,EAAA,QAAE,CAACC,QAAQ,CAAClB,EAAe,SACjDgB,EAAWG,KAAKC,KAAK,CAACH,EACxB,CAAE,MAAOtB,EAAK,CAER,AAACD,EAAgBC,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,2CAA2C,EAAEtB,EAAc,cAAc,CAAC,CAAEL,EAE9F,CAEA,IAAM4B,EAAS,CACb,GAAGP,CAAQ,CACXQ,QAASb,EAAKa,OAAO,CACrB,GAAIb,KAAsBe,MAAjBD,YAAY,CAAiB,CAAEA,aAAcd,EAAKc,YAAY,AAAC,EAAI,CAAC,CAAC,CAC9E,QAAmBC,IAAff,EAAKgB,KAAK,CAAiB,CAAEA,MAAOhB,EAAKgB,KAAK,AAAC,EAAI,CAAC,CAAC,CACzD,QAA8BD,IAA1Bf,EAAKiB,gBAAgB,CAAiB,CAAEA,iBAAkBjB,EAAKiB,gBAAgB,AAAC,EAAI,CAAC,CAAC,CAC1F,GAAIjB,KAAkCe,MAA7BG,wBAAwB,CAAiB,CAAEA,yBAA0BlB,EAAKkB,wBAAwB,AAAC,EAAI,CAAC,CAAC,CAClH,QAA2BH,IAAvBf,EAAKmB,aAAa,CAAiB,CAAEA,cAAenB,EAAKmB,aAAa,AAAC,EAAI,CAAC,CAAC,CACjF,QAA4BJ,IAAxBf,EAAKoB,cAAc,CAAiB,CAAEA,eAAgBpB,EAAKoB,cAAc,AAAC,EAAI,CAAC,CAAC,AACtF,CAEA,OAAM,EAAA,QAAE,CAACC,SAAS,CAAChC,EAAemB,KAAKc,SAAS,CAACV,EAAQ,KAAM,GAAK,KAAM,QAC5E,CAYA,eAAeW,IACb,GAAI,CACF,IAAMjB,EAAU,MAAM,EAAA,QAAE,CAACC,QAAQ,CAAClB,EAAe,SAC3CmC,EAAShB,KAAKC,KAAK,CAACH,GAQ1B,MAAO,CACLO,QARcY,MAAMC,OAAO,CAACF,EAAOX,OAAO,EACxCW,EAAOX,OAAO,CAACc,GAAG,CAAC,AAACC,IAA+B,AAAC,CAClDC,KAAMC,OAAOF,EAAEC,IAAI,EAAI,IACvBE,MAA0B,AAAnB,iBAAOH,EAAEG,KAAK,CAAgBH,EAAEG,KAAK,CAAG,EAC/CC,MAAOJ,EAAEI,KAAK,CAAGF,OAAOF,EAAEI,KAAK,OAAIjB,CACrC,CAAC,GACD,EAAE,CAGJD,aAA6C,UAA/B,OAAOU,EAAOV,YAAY,CAAgBU,EAAOV,YAAY,CAAGC,OAC9EC,MAAwB,SAAjBQ,EAAOR,KAAK,EAAgC,UAAjBQ,EAAOR,KAAK,CAAeQ,EAAOR,KAAK,MAAGD,EAC5EE,iBAAqD,UAAnC,OAAOO,EAAOP,gBAAgB,CAAgBO,EAAOP,gBAAgB,MAAGF,EAC1FG,yBAAqE,UAA3C,OAAOM,EAAON,wBAAwB,CAAgBM,EAAON,wBAAwB,MAAGH,EAClHI,cAA+C,UAAhC,OAAOK,EAAOL,aAAa,CAAgBK,EAAOL,aAAa,MAAGJ,EACjFK,eAAgBK,MAAMC,OAAO,CAACF,EAAOJ,cAAc,EAAII,EAAOJ,cAAc,CAACa,MAAM,CAAEL,AAAD,GAA6B,UAAb,OAAOA,GAAkBb,MAC/H,CACF,CAAE,MAAO/B,EAAK,CAIZ,OAHI,AAACD,EAAgBC,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,sCAAsC,EAAEtB,EAAc,kBAAkB,CAAC,CAAEL,GAEpF,CAAE6B,QAAS,EAAE,AAAC,CACvB,CACF,CAoCO,eAAegC,IACpB,IAAMC,EAAMC,KAAKD,GAAG,GACpB,GAAInD,GAAgBmD,EAAMlD,EAzHV,IA0Hd,GA1HqB,GAyHeC,CAC7BF,EAGT,AA7H6B,IA6HvBqD,EAAW,EAJgC,IAI1BzB,IACjB0B,EAzCR,AAyCyBf,SAzChBA,EACP,IAAMrB,EAAyB,EAAE,CAajC,GAVIvB,QAAQC,GAAG,CAAC4C,kBAAkB,EAAE,AAClCtB,EAAQuB,IAAI,CAAC,CAAEP,KAAMvC,QAAQC,GAAG,CAAC4C,kBAAkB,CAAEJ,MAAO,EAAGC,MAAO,KAAM,GAI1E1C,QAAQC,GAAG,CAAC8C,SAAS,EAAE,AACzBxB,EAAQuB,IAAI,CAAC,CAAEP,KAAMvC,QAAQC,GAAG,CAAC8C,SAAS,CAAEN,MAAO,EAAGC,MAAO,KAAM,GAIjE1C,QAAQC,GAAG,CAAC+C,UAAU,CACxB,CAD0B,GACrB,IAAMrC,KAAOX,QAAQC,GAAG,CAAC+C,UAAU,CAACC,KAAK,CAAC,KAAM,CACnD,IAAMC,EAAUvC,EAAIwC,IAAI,GACpBD,GAAS3B,EAAQuB,IAAI,CAAC,CAAEP,KAAMW,EAAST,MAAO,CAAE,EACtD,CAaF,OARuB,GAAG,CAAtBlB,EAAQ6B,MAAM,EAChB7B,EAAQuB,IAAI,CAAC,CACXP,KAAM,EAAA,OAAI,CAACc,OAAO,CAACrD,QAAQsD,GAAG,GAAI,MAClCb,MAAO,EACPC,MAAO,QACT,GAGKnB,CACT,IAaQqC,EAAaF,EAASnC,OAAO,CAAC6B,MAAM,CAAG,EAAIM,EAASnC,OAAO,CAAGoC,EAC9DE,EAAO,IAAIC,IACXvC,EAAUqC,EAAWjB,MAAM,CAAC,AAACL,IACjC,IAAMyB,EAAa,EAAA,OAAI,CAACV,OAAO,CAACf,EAAEC,IAAI,QACtC,CAAIsB,EAAKG,GAAG,CAACD,KACbF,EAAKI,GAAG,CAACF,EADiB,EAEnB,EACT,GAHmC,AAM7BG,EAAkBlE,QAAQC,GAAG,CAACkE,sBAAsB,EAAInE,QAAQC,GAAG,CAACmE,aAAa,CACjFC,EAAWrE,QAAQC,GAAG,CAACqE,sBAAsB,EAAItE,QAAQC,GAAG,CAACsE,KAAK,CAClEC,EAAoBxE,QAAQC,GAAG,CAACwE,2BAA2B,CAC3DC,EAAkB1E,QAAQC,GAAG,CAAC0E,yBAAyB,CACvDC,EAAmB5E,QAAQC,GAAG,CAAC4E,uBAAuB,CAc5D,OAZAxE,EAAe,SACbkB,EACAuD,KAAMC,SAAS/E,QAAQC,GAAG,CAAC+E,aAAa,EAAIhF,QAAQC,GAAG,CAACgF,IAAI,EAAI,OAAQ,IACxEzD,aAAckC,EAASlC,YAAY,GAAK0C,CAAD,CAAmBa,SAASb,EAAiB,IAAM,GAAA,CAAI,CAC9FxC,MAAOgC,EAAShC,KAAK,GAAmB,CAAd,QAAC2C,GAAoC,UAAbA,EAAuBA,EAAW,MAAA,CAAM,CAC1F1C,iBAAkB+B,EAAS/B,gBAAgB,GAAK6C,CAAD,CAAqBO,SAASP,EAAmB,IAAM,IAAA,CAAO,CAC7G5C,yBAA0B8B,EAAS9B,wBAAwB,GAAK8C,CAAD,CAAmBK,SAASL,EAAiB,IAAM,KAAA,CAAQ,CAC1H7C,cAAe6B,EAAS7B,aAAa,GAAK+C,CAAD,CAAoBG,SAASH,EAAkB,IAAM,EAAA,CAAE,CAChG9C,eAAgB4B,EAAS5B,cAAc,EAAI,EAAE,AAC/C,EACAxB,EAAYkD,EAELnD,CACT,gDA5JO,SAASG,EACdH,EAAe,KACfC,EAAY,CACd,oECzCA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAqBA,EAAA,EAAA,CAAA,CAAA,OAlBA,SAASb,EAAgBC,CAAY,EACnC,GAAI,CAAC,CAACA,aAAeC,KAAAA,CAAK,CAAG,OAAO,EACpC,IAAMC,EAAQF,EAA8BE,IAAI,CAChD,MAAOA,AAAS,cAAYA,AAAS,eAAaF,EAAIG,OAAO,CAACC,QAAQ,CAAC,SACzE,CAgBA,SAASoF,EAAiBC,CAAyB,EACjD,GAAI,CAACA,EAAO,OAAO,KACnB,IAAMC,EAAK,IAAI3B,KAAK0B,GAAOE,OAAO,GAClC,OAAOC,OAAOC,QAAQ,CAACH,GAAMA,EAAK,IACpC,CAEA,SAASI,EAAkBC,CAAsB,CAAEC,CAAoB,SACrE,AAAe,MAAXD,GAA4B,MAATC,AAAe,EAAO,KACtC,SACLD,EACAC,MAAOC,KAAKC,GAAG,CAACF,EAAOD,EACzB,CACF,CAEA,SAASI,EAAoBC,CAK5B,EACC,IAAMC,EAAiBP,EACrBN,EAAiBY,EAAKE,SAAS,EAC/Bd,EAAiBY,EAAKG,UAAU,UAElC,AAAIF,GAEGP,EACLN,EAAiBY,EAAKI,OAHJ,IAGe,EACjChB,CAJyBa,CAIRD,EAAKK,UAAU,EAEpC,CAEA,SAASC,EAAsBN,CAK9B,EACC,IAAMO,EAASR,EAAoBC,GACnC,GAAKO,CAAD,CACJ,MADa,CACNA,EAAOX,IADMjE,CACD,CAAG4E,EAAOZ,OAAO,AACtC,CAuBA,eAAeuB,EAAWC,CAAgB,EACxC,GAAI,CAEF,OADA,MAAM,EAAA,QAAE,CAACC,MAAM,CAACD,IACT,CACT,CAAE,MAAOvH,EAAK,CAKZ,OAHI,AAACD,EAAgBC,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,gDAAgD,EAAE4F,EAAS,CAAC,CAAC,CAAEvH,GAExE,EACT,CACF,CAEA,eAAeyH,EAAgBF,CAAgB,CAAEG,CAA8B,EAC7E,GAAI,CACF,IAAMpG,EAAU,MAAM,EAAA,QAAE,CAACC,QAAQ,CAACgG,EAAU,SAC5C,OAAO/F,KAAKC,KAAK,CAACH,EACpB,CAAE,MAAOtB,EAAK,CAKZ,OAHI,AAACD,EAAgBC,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,wCAAwC,EAAE4F,EAAS,CAAC,CAAC,CAAEvH,GAEhE0H,CACT,CACF,CAEA,eAAeC,EAAaJ,CAAgB,EAC1C,GAAI,CACF,OAAO,MAAM,EAAA,QAAE,CAAChG,QAAQ,CAACgG,EAAU,QACrC,CAAE,MAAOvH,EAAK,CAER,AAACD,EAAgBC,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,kCAAkC,EAAE4F,EAAS,CAAC,CAAC,CAAEvH,GAEjE,MACF,CADS+B,AAEX,CAUA,eAAe8F,EACbC,CAAkC,CAClCC,EAT8B,EASS,EAEvC,EAFgBH,EAEVI,EAAqC,AAAIvF,MAAMqF,EAAUpE,MAAM,EACjEuE,EAAY,EAEhB,eAAeC,IACb,KAAOD,EAAYH,EAAUpE,MAAM,EAAE,CACnC,IAAMyE,EAAMF,IACZ,GAAI,CACF,IAAMxC,EAAQ,MAAMqC,CAAS,CAACK,EAAI,GAClCH,CAAO,CAACG,EAAI,CAAG,CAAEC,OAAQ,YAAa3C,OAAM,CAC9C,CAAE,MAAO4C,EAAQ,CACfL,CAAO,CAACG,EAAI,CAAG,CAAEC,OAAQ,kBAAYC,CAAO,CAC9C,CACF,CACF,CAEA,IAAMC,EAAcrC,KAAKsC,GAAG,CAACR,EAAOD,EAAUpE,MAAM,EAC9C8E,EAA2B,EAAE,CACnC,IAAK,IAAIpB,EAAI,EAAGA,EAAIkB,EAAalB,IAAK,AACpCoB,EAAQpF,IAAI,CAAC8E,KAGf,OADA,MAAMO,QAAQC,GAAG,CAACF,GACXR,CACT,CAGA,SAASW,EAAsBC,CAA4B,CAAEC,CAAgB,EAC3E,GAAI,CAACD,GAAO,CAACA,EAAIE,IAAI,CAAE,OAAO,KAG9B,IAAMC,EAAQF,EAASG,OAAO,CAAC,UAAW,IAAIzF,KAAK,CAAC,KAIpD,MAAO,CACL0F,IAJU5D,SAAS0D,CAAK,CAAC,EAAE,CAAE,KAAO,EAKpCG,GAJSH,CAAK,CAAC,EAAE,EAAI,GAKrBI,GAAKP,EAAIQ,UAAU,EAAgBR,EAAIO,EAAE,EAAe,GACxDL,KAAMF,EAAIE,IAAI,CACdO,QAAUT,EAAI5H,IAAI,EAAiC4H,EAAIS,OAAO,EAAgC,CAAC,CACjG,CACF,CASO,eAAeC,EACpBC,CAAmB,EAGnB,MAAOC,CADQ,MAAMC,EAA2BF,EAAAA,EAClCG,MAAM,AACtB,CAeO,eAAeD,EACpBF,CAAmB,CACnBI,CAA+B,CAC/BC,CAA0B,EAE1B,GAAI,CAAE,MAAMtC,EAAWiC,GAAe,MAAO,CAAEG,OAAQ,EAAE,CAAEG,UAAW,CAAE,EAGxE,IAAMG,EAAYF,CADJ,MAAM,EAAA,QAAE,CAACC,OAAO,CAACR,EAAAA,EACPtG,MAAM,CAAC,AAACgH,GAAMA,EAAEC,QAAQ,CAAC,UAAUnD,IAAI,GACzDoD,EAAmBH,EAAUtG,MAAM,CAWzC,IAAI0G,IALiBrI,IAAnB4H,GACAC,KAAsB7H,OACtB6H,GAAqB,GACrBO,GAAoBP,EAEF,CAIlB,GAAIS,GAAoBF,EACtB,MAAO,CAAET,OAAQC,EAAiBE,AADM,UACKM,CAAiB,EAGhE,IAAMG,EAAWN,EAAUO,KAAK,CAACF,AAPRT,GAUnBY,EAAgBF,EAAS3H,GAAG,CAChC,AAAC8H,GAAS,IACRhD,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC8I,EAAakB,GAAO,OAElEC,EAAU,MAAM7C,EAAgB2C,GAEhCG,EAA4B,EAAE,CACpC,IAAK,IAAIvD,EAAI,EAAGA,EAAIkD,EAAS5G,MAAM,CAAE0D,IAAK,CACxC,IAAMoC,EAASkB,CAAO,CAACtD,EAAE,CACnBwB,EAAwB,AAAlBY,gBAAOpB,MAAM,CAAmBoB,EAAO/D,KAAK,CAAG,KAC3D,GAAImD,EAAK,CACP,IAAMgC,EAAQjC,EAAsBC,EAAK0B,CAAQ,CAAClD,EAAE,EAChDwD,GAAOD,EAAUvH,IAAI,CAACwH,EAC5B,CACF,CAKA,MAAO,CAAElB,OADM,CACE9H,GADE+H,KAAoBgB,EAAU,CAAC5D,IAAI,CAAC,CAACC,EAAGC,IAAMD,EAAEiC,GAAG,CAAGhC,EAAEgC,GAAG,EACrDY,UAAWM,CAAiB,CACvD,CAGA,IAAMK,EAAgBR,EAAUrH,GAAG,CAChC8H,AAAD,GAAU,IACRhD,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC8I,EAAakB,GAAO,OAElEC,EAAU,MAAM7C,EAAgB2C,GAEhCd,EAAyB,EAAE,CACjC,IAAK,IAAItC,EAAI,EAAGA,EAAI4C,EAAUtG,MAAM,CAAE0D,IAAK,CACzC,IAAMoC,EAASkB,CAAO,CAACtD,EAAE,CACnBwB,EAAMY,AAAkB,gBAAXpB,MAAM,CAAmBoB,EAAO/D,KAAK,CAAG,KAC3D,GAAImD,EAAK,CACP,IAAMgC,EAAQjC,EAAsBC,EAAKoB,CAAS,CAAC5C,EAAE,EACjDwD,GAAOlB,EAAOtG,IAAI,CAACwH,EACzB,CACF,CAEA,MAAO,CAAElB,OAAQA,EAAO3C,IAAI,CAAC,CAACC,EAAGC,IAAMD,EAAEiC,GAAG,CAAGhC,EAAEgC,GAAG,EAAGY,UAAWM,CAAiB,CACrF,CAcO,eAAeU,EACpBC,CAAe,CACfC,CAAmC,EAEnC,IAiHI0C,EACAC,EAgCAV,EAWAmB,EAYA/B,EAeAsC,EAxLE1D,EAAU,MAAMvD,EACpB,EAAA,OAAI,CAAChH,IAAI,CAACqK,EAAS,YACnB,CAAC,GAGGG,EAAgB,MAAMxB,EAC1B,EAAA,OAAI,CAAChJ,IAAI,CAACqK,EAAS,WACnBC,GAAapB,eACboB,GAAanB,mBAETF,EAASuB,EAAcvB,MAAM,CAG7BwB,EAAaxB,EAAOyB,IAAI,CAAC,AAACC,GAAiB,gBAAXA,EAAEtC,IAAI,EACtCuC,EAAe3B,EAAOyB,IAAI,CAAEC,AAAD,GAAkB,kBAAXA,EAAEtC,IAAI,EACxCwC,EAAY5B,EAAOyB,IAAI,CAAC,AAACC,GAAiB,eAAXA,EAAEtC,IAAI,EAErCyC,EAAkBL,GAAY7B,SAClC,CAAC,EAGGmC,EAAU,IAAIC,IACdC,EAA8C,EAAE,CAEtD,IAAK,IAAMd,KAASlB,EAAQ,CAC1B,GAAmB,qBAAfkB,EAAM9B,IAAI,CAAyB,CACrC,IAAM6C,EAAIf,EAAMvB,OAAO,CACvBqC,EAAkBtI,IAAI,CAACuI,GACvBH,EAAQI,GAAG,CAACD,EAAEE,QAAQ,CAAE,CACtBA,SAAUF,EAAEE,QAAQ,CACpBC,KAAMH,EAAEG,IAAI,CACZC,MAAOJ,EAAE3I,KAAK,EAAI2I,EAAEK,MAAM,CAC1BhJ,MAAO2I,EAAE3I,KAAK,EAAI2I,EAAEK,MAAM,CAC1B5D,OAAQ,YACR6D,cAAeN,EAAEM,aAAa,CAC9BC,OAAQP,EAAEO,MAAM,CAChBF,OAAQL,EAAEK,MAAM,CAChBxF,YAAaoE,EAAMzB,EAAE,AACvB,EACF,CAEA,GAAmB,oBAAfyB,EAAM9B,IAAI,CAAwB,CACpC,IAAM6C,EAAIf,EAAMvB,OAAO,CACjBjD,EAAOoF,EAAQW,GAAG,CAACR,EAAEE,QAAQ,EAC/BzF,IACFA,EAAKgC,AADG,MACG,CAAgB,OAAbuD,EAAEvD,MAAM,CAAY,WAAa,QAC/ChC,EAAKK,UAAU,CAAGmE,EAAMzB,EAAE,CAC1B/C,EAAKE,SAAS,CAAGqF,EAAErF,SAAS,CAC5BF,EAAKG,UAAU,CAAGoF,EAAEpF,UAAU,CAC9BH,EAAKgG,QAAQ,CAAG1F,EAAsB,CACpCJ,UAAWqF,EAAErF,SAAS,CACtBC,WAAYoF,EAAEpF,UAAU,CACxBC,YAAaJ,EAAKI,WAAW,CAC7BC,WAAYmE,EAAMzB,EACpB,AADsB,GAElBwC,EAAEU,KAAK,EAAE,CACXjG,EAAKiG,KAAK,CAAG,CACXC,KAAMX,EAAEU,KAAK,CAACC,IAAI,CAClBnM,QAASwL,EAAEU,KAAK,CAAClM,OAAO,CACxBoM,MAAOZ,EAAEU,KAAK,CAACE,KAAK,CACtB,EAGN,CACF,CAGA,GAAIb,EAAkBhI,MAAM,CAAG,EAAG,CAChC,IAAM8I,EAAmBd,EAAkB/I,GAAG,CAC3CgJ,AAAD,GAAO,IACLlE,EACE,EAAA,OAAI,CAAChH,IAAI,CAACqK,EAAS,QAASa,EAAEE,QAAQ,CAAE,aACxC,OAGAY,EAAiB,MAAM5E,EAAgB2E,GAE7C,IAAK,IAAIpF,EAAI,EAAGA,EAAIsE,EAAkBhI,MAAM,CAAE0D,IAAK,CACjD,IAAMuE,EAAID,CAAiB,CAACtE,EAAE,CACxBoC,EAASiD,CAAc,CAACrF,EAAE,CAC1BsF,EAA4B,cAAlBlD,EAAOpB,MAAM,CAAmBoB,EAAO/D,KAAK,CAAG,KAC/D,GAAIiH,EAAS,CACX,IAAMtG,EAAOoF,EAAQW,GAAG,CAACR,EAAEE,QAAQ,EAEnC,GADAzF,EAAK2F,KAAK,CAAIW,EAAQX,KAAK,EAAe3F,EAAK2F,KAAK,CAChDW,EAAQC,KAAK,EAAI,AAAyB,iBAAlBD,EAAQC,KAAK,CAAe,CACtD,IAAMC,EAAWF,EAAQC,KAAK,CAC9BvG,EAAKuG,KAAK,CAAG,CACXL,KAAOM,EAASN,IAAI,EAAe,UACnCO,OAAQD,EAASC,MAAM,AACzB,CACF,CAEA,GAAe,eAAXlB,EAAEG,IAAI,CAAmB,CAC3B,IAAMgB,EAASJ,EAAQI,MAAM,CACzBA,GAAqC,UAA3B,AAAqC,OAA9BA,EAAOC,QAAQ,GAClC3G,EAAK4G,kBAAkB,CAAGF,EAAOC,QAAAA,AAAQ,CAE7C,CACF,CACF,CACF,CAEA,IAAME,EAAQxK,MAAMyK,IAAI,CAAC1B,EAAQ2B,MAAM,IACjCC,EAAiBH,EAAMhK,MAAM,CAAEoK,AAAD,GAAoB,aAAbA,EAAEjF,MAAM,EAAiB1E,MAAM,CACpE4J,EAAcL,EAAMhK,MAAM,CAAC,AAACoK,GAAmB,UAAbA,EAAEjF,MAAM,EAAc1E,MAAM,CAG9D6J,EAAkBN,EAAM9B,IAAI,CAAEkC,AAAD,GAAoB,AAAbA,YAAEjF,MAAM,EAC5CoF,EAAaD,EACfA,EAAgBxB,KAAK,EAAIwB,EAAgBvK,KAAK,EAAIuK,EAAgBrB,MAAM,MACxEnK,EAMJ,GAAIuJ,EAAW,CAEb,IAAMsC,EADctC,AACHqC,EADatE,OAAO,CACRgD,KAAK,CAC9BuB,IACFH,EAAeG,EAAStB,EADZ,EACgB,EAAI,QAChCoB,EAAiBE,EAASzN,OAAO,EAAIyN,EAASrB,KAAK,OAAIxK,EAE3D,CAGA,GAAI,CAAC2L,EAAgB,CACnB,IAAMG,EAAmB,IAAInE,EAAO,CACjCoE,OAAO,GACP3C,IAAI,CAAC,AAACC,GAAiB,oBAAXA,EAAEtC,IAAI,EAA4E,UAAjDsC,EAAE/B,OAAO,CAA6BjB,MAAM,EAC5F,GAAIyF,EAAkB,CAEpB,IAAMG,EADgBH,AACFE,EADmB1E,OAAO,CACZgD,KAAK,CACnC2B,IACFP,EAAeA,GAAgBO,EAAY1B,EAD5B,EACgC,EAAI,QACnDoB,EAAiBM,EAAY7N,OAAO,EAAI6N,EAAYzB,KAAK,OAAIxK,EAEjE,CACF,CAEA,IAAIqG,EAAoB,UAOxB,GANIiD,EAAcjD,EAAS,YAClBkD,EAAWlD,EAAS,SACpB6E,EAAMgB,IAAI,CAAC,AAACZ,GAAMA,AAAa,gBAAXjF,MAAM,IAAmBA,EAAS,SAAA,EAIhD,YAAXA,EAAsB,CACxB,IAAM8F,EAAoBjB,EAAM9B,IAAI,CAClC,AAACkC,GAAiB,eAAXA,EAAEvB,IAAI,EAAkC,cAAbuB,EAAEjF,MAAM,EAExC8F,GAAmBlB,oBAAoB,CACzCA,EAAqBkB,EAAkBlB,kBAAAA,AAAkB,CAE7D,CAIA,GAAe,YAAX5E,EAAsB,CACxB,IAAMgG,EAAiBnB,EAAMhK,MAAM,CAAC,AAACoK,GAAmB,cAAbA,EAAEjF,MAAM,EAC7CiG,EAAgBD,CAAc,CAACA,EAAe1K,MAAM,CAAG,EAAE,CAC3D2K,IACFF,EAAqC,SADpB,MACHE,EAAcvC,IAAI,CAAoB,aAAe,MAAA,CAEvE,CAEA,IAAMwC,EAAYpD,GAAY/B,IAAM,GAC9BoF,EAAY7E,CAAM,CAACA,EAAOhG,MAAM,CAAG,EAAE,CAGrC8K,EAAcvB,EACjBtK,GAAG,CAAC,AAACyD,GAASD,EAAoBC,IAClCnD,MAAM,CAAE0D,AAAD,GAAqE,AAAXA,UAapE,GAZI6H,EAAY9K,MAAM,CAAG,EACvB0I,CAD0B,CAlZ9B,AAmZexF,SAnZeC,AAArBD,CAAuE,EAC9E,GAAuB,IAAnBC,EAAQnD,MAAM,CAAQ,OAAO,EAEjC,IAAMoD,EAAS,IAAID,EAAQ,CAACE,IAAI,CAAC,CAACC,EAAGC,IAAMD,EAAEjB,OAAO,CAAGkB,EAAElB,OAAO,EAC5DmB,EAAU,EACVC,EAAUL,CAAM,CAAC,EAAE,CAEvB,IAAK,IAAIM,EAAI,EAAGA,EAAIN,EAAOpD,MAAM,CAAE0D,IAAK,CACtC,IAAMC,EAAOP,CAAM,CAACM,EAAE,CACtB,GAAIC,EAAKtB,OAAO,EAAIoB,EAAQnB,KAAK,CAAE,CACjCmB,EAAQnB,KAAK,CAAGC,KAAKC,GAAG,CAACiB,EAAQnB,KAAK,CAAEqB,EAAKrB,KAAK,EAClD,QACF,CACAkB,GAAWC,EAAQnB,KAAK,CAAGmB,EAAQpB,OAAO,CAC1CoB,EAAUE,CACZ,CAGA,OADAH,AACOA,GADIC,EAAQnB,KAAK,CAAGmB,EAAQpB,OAAO,AAAPA,CAErC,EAgYoCyI,GACvBF,IAAcjD,GAAgBC,CAAAA,CAAS,CAEhDc,EAAW,AAFwC,CAA7B,GAEPrI,KADD,AACM0K,CADLpD,GAAgBC,CAAAA,CAAS,CAAGnC,EAAE,EAClBxD,OAAO,GAAK,IAAI5B,KAAKuK,GAAW3I,OAAO,GACzD2I,GAAaC,IACtBnC,EACE,IAAIrI,CAF2B,IAEtBwK,EAAUpF,EAAE,EAAExD,OAAO,GAAK,IAAI5B,KAAKuK,GAAW3I,OAAO,EAAA,EAKnD,YAAXyC,GAAmC,YAAXA,EAAsB,CAChD,IAAMuG,EAAcJ,GAAWpF,IAAMmF,EACrC,GAAIK,EAAa,CACf,IAAMC,EAAS,MAAM,CAAA,EAAA,EAAA,SAAA,AAAS,GAE1BC,CADoB9K,KAAKD,GAAG,GAAK,IAAIC,KAAK4K,GAAahJ,OAAO,GAC5CiJ,EAAO3M,gBAAgB,EAAE,CAC7CyM,EAAU,EAAA,CAEd,CACF,CAQA,MAJe,YAAXtG,GAAwB6E,EAAMvJ,MAAM,CAAG,GAAK,CAACuJ,EAAMgB,IAAI,CAAC,AAACZ,GAAmB,cAAbA,AAA2B,EAAzBjF,MAAM,GACzEsG,GAAU,EAAA,EAGL,CACLI,MAAOvD,EAAeuD,KAAK,EAAI,EAAA,OAAI,CAACC,QAAQ,CAACjE,GAC7CkE,UACEzD,EAAeyD,SAAS,EACvBhE,GAASgE,WACV,iBACF5G,YACAkG,EACAW,UAAWV,GAAWpF,IAAMmF,EAC5BY,YAAc7D,CAAD,GAAiBC,CAAAA,CAAS,EAAGnC,SAC1C8D,SACAvD,EACAyF,WAAYlC,EAAMvJ,MAAM,gBACxB0J,cACAE,WACAlB,aACAoB,eACAC,EACAC,oCACAV,UACA0B,EACAP,cACAiB,kBAAmBnE,EAAcpB,SAAS,AAC5C,CACF,CAEO,eAAewF,EACpBvE,CAAe,CACfe,CAAgB,EAEhB,IAoDI0E,EApDEjB,EAAU,EAAA,OAAI,CAAC7O,IAAI,CAACqK,EAAS,QAASe,GAC5C,GAAI,CAAE,MAAMvE,EAAWgI,GAAW,OAAO,KAGzC,GAAM,CACJC,EACAC,EACAC,EACAC,EACAC,EACAC,EACD,CAAG,MAAMnH,QAAQoH,UAAU,CAAC,CAC3BpI,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC6O,EAAS,aAAc,MACvE7H,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC6O,EAAS,mBAAevN,GACxE0F,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC6O,EAAS,oBAAgBvN,GACzE4F,EAAa,EAAA,OAAI,CAAClH,IAAI,CAAC6O,EAAS,eAChC3H,EAAa,EAAA,OAAI,CAAClH,IAAI,CAAC6O,EAAS,eAChChG,EAAgB,EAAA,OAAI,CAAC7I,IAAI,CAACqK,EAAS,YACpC,EAEK4B,EAAmC,cAAzB6C,EAAcnH,MAAM,CAAmBmH,EAAc9J,KAAK,CAAG,KACvEqK,EAAQN,AAAuB,gBAAXpH,MAAM,CAAmBoH,EAAY/J,KAAK,MAAG1D,EACjEyH,EAAiC,cAAxBiG,EAAarH,MAAM,CAAmBqH,EAAahK,KAAK,MAAG1D,EACpEgO,EAAiC,cAAxBL,EAAatH,MAAM,CAAmBsH,EAAajK,KAAK,MAAG1D,EACpEiO,EAAiC,cAAxBL,EAAavH,MAAM,CAAmBuH,EAAalK,KAAK,MAAG1D,EACpEkO,EAA+C,cAA/BL,EAAoBxH,MAAM,CAAmBwH,EAAoBnK,KAAK,CAAG,EAAE,CAG3FyK,EAAkB1G,GAAQlD,UAC1B6J,EAAmB3G,GAAQjD,WAC3B6J,EAAiBH,EAAc9E,IAAI,CACvC,AAACC,GAAiB,qBAAXA,EAAEtC,IAAI,EAA4BsC,EAAE/B,OAAO,CAA6BwC,QAAQ,GAAKA,GAExFwE,EAAgBJ,EAAc9E,IAAI,CACrCC,AAAD,GAAkB,oBAAXA,EAAEtC,IAAI,EAA2BsC,EAAE/B,OAAO,CAA6BwC,QAAQ,GAAKA,GAGvFrF,EAAc4J,GAAgBjH,IAAM,GACpC1C,EAAa4J,GAAelH,GAE5BiD,EAAW1F,EAAsB,CACrCJ,UAAW4J,EACX3J,WAAY4J,cACZ3J,aACAC,CACF,GAGM6J,EAAgBR,GAAUpD,GAASI,OAGnChB,EAAQY,GAASZ,MAAqB,QAE/B,eAATA,GAAyBwE,IAC3BC,EAAoB,CAClBxD,QAFwC,CAE7BuD,EAAcvD,QAAQ,EAAe,oBAChDhB,MAAQuE,EAAcvE,KAAK,EAAgBW,GAASX,OAAoB,aACxEyE,QAAS/N,MAAMC,OAAO,CAAC4N,EAAcE,OAAO,EAAKF,EAAcE,OAAO,CAAgBzO,OACtF0O,QAASH,EAAcG,OAAO,CAChC,EAIF,IAAMC,EAAkBL,GAAehH,QACjCsH,EAAUnH,EACO,UAAlBA,EAAOpB,MAAM,CACbsI,GAAiBtI,SAAW,QAEjC,MAAO,UACLyD,OACAC,EACAC,MAAQW,GAASX,OAAoBF,EACrC7I,MAAQ0J,GAASX,OAAoBF,EACrCzD,OAAQiI,EAAiBM,EAAU,QAAU,WAAc,YAC3D1E,cAAgBS,GAAST,eAA4B,GACrDC,OAASQ,GAASR,QAAqB,GACvCF,OAASU,GAASV,QAAqB,eACvCxF,aACAC,EACAH,UAAW4J,EACX3J,WAAY4J,WACZ/D,EACA0D,MAAOQ,EACP9G,OAAQA,QAAUzH,SAClBgO,SACAC,EACAtD,QAASA,QAAW3K,EACpB6O,WAAYL,EACZvD,mBAAoBuD,GAAmBxD,QACzC,CACF,CAEO,eAAe8D,EAAa/F,CAAe,EAChD,IAoFIkC,EACAwE,EAmCArD,EAaAO,EArIEnF,EAAc,EAAA,OAAI,CAAC9I,IAAI,CAACqK,EAAS,WACnCgG,EAAY,EACZ1I,EAAoB,UACpB2I,EAAY,EACZ3D,EAAiB,EACjB6B,EAAY,GAEV+B,EAAuB,IAAI5M,IAC3B6M,EAAkB,IAAI7M,IACtB8M,EAAsB,IAAI9M,IAE1B+M,EAA8D,EAAE,CAEtE,GAAI,MAAM7J,EAAWiC,GAAc,CAEjC,IAAMS,EADQ,AACIF,OADE,EAAA,QAAE,CAACC,OAAO,CAACR,EAAAA,EACPtG,MAAM,CAAC,AAACgH,GAAMA,EAAEC,QAAQ,CAAC,UAAUnD,IAAI,GAC/D+J,EAAY9G,EAAUtG,MAAM,CAG5B,IAAM8G,EAAgBR,EAAUrH,GAAG,CACjC,AAAC8H,GAAS,IACRhD,EAAsC,EAAA,OAAI,CAAChH,IAAI,CAAC8I,EAAakB,GAAO,OAElEC,EAAU,MAAM7C,EAAgB2C,GAGtC,IAAK,IAAIpD,EAAI,EAAGA,EAAI4C,EAAUtG,MAAM,CAAE0D,IAAK,CACzC,IAAMoC,EAASkB,CAAO,CAACtD,EAAE,CACnBwB,EAAwB,cAAlBY,EAAOpB,MAAM,CAAmBoB,EAAO/D,KAAK,CAAG,KAC3D,GAAI,CAACmD,EAAK,SACV,IAAMgC,EAAQjC,EAAsBC,EAAKoB,CAAS,CAAC5C,EAAE,EACrD,GAAKwD,CAAD,EAEJ,GADAqE,CADY,CACArE,EAAMzB,EAAE,CACD,qBAAfyB,EAAM9B,IAAI,CAAyB,CACrCiI,IACA,IAAM/P,EAAO4J,EAAMvB,OAAO,CACpBwC,EAAW7K,EAAK6K,QAAQ,CACxBC,EAAQ9K,EAAK8K,IAAI,EAAe,QACtCqF,EAAiB/N,IAAI,CAAC,UAAEyI,OAAUC,CAAK,GACrB,cAAc,CAA5B9K,EAAK8K,IAAI,GACXkF,EAAqBzM,GAAG,CAACsH,GACzBqF,EAAoB3M,GAAG,CAACsH,GAE5B,CACA,GAAIjB,AAAe,sBAAT9B,IAAI,CAAwB,CACpCsE,IACA,IAAMpM,EAAO4J,EAAMvB,OAAO,CAC1B4H,EAAgB1M,GAAG,CAACvD,EAAK6K,QAAQ,CACnC,CACmB,AAAfjB,oBAAM9B,IAAI,GAAsBV,EAAS,WAAA,EAC1B,eAAfwC,EAAM9B,IAAI,GAAmBV,EAAS,QAAA,EAC5C,CAEe,YAAXA,GAAwB2I,EAAY,IAAG3I,EAAS,SAAA,CACtD,CAKA,IAAIgJ,EAAqB,EACzB,GAAIJ,EAAqBK,IAAI,CAAG,EAAG,CACjC,IAAMC,EAAgB,IAAIN,EAAqB,CAAC/N,MAAM,CACpD,AAACiG,GAAO,CAAC+H,EAAgB3M,GAAG,CAAC4E,IAE/B,GAAIoI,EAAc5N,MAAM,CAAG,EAAG,CAC5B,IAAM6N,EAAe,MAAM9I,QAAQC,GAAG,CACpC4I,EAAc3O,GAAG,CAAC,AAACuG,GACjBzB,EACE,EAAA,OAAI,CAAChH,IAAI,CAACqK,EAAS,QAAS5B,EAAI,eAChC,QAIN,IAAK,IAAI9B,EAAI,EAAGA,EAAIkK,EAAc5N,MAAM,CAAE0D,IAAK,AACzCmK,CAAY,CAACnK,EAAE,EAAgC,MAAM,CAAlCmK,CAAY,CAACnK,EAAE,CAAEgB,MAAM,CAC5C6I,EAAgB1M,GAAG,CAAC+M,CAAa,CAAClK,EAAE,EAEpCgK,GAGN,CACF,CAKA,GAAe,YAAXhJ,GAAwB8I,EAAoBG,IAAI,CAAG,EAAG,CACxD,IAAMI,EAAe,IAAIP,EAAoB,CAACjO,MAAM,CAClD,AAACiG,GAAO,CAAC+H,EAAgB3M,GAAG,CAAC4E,IAE/B,GAAIuI,EAAa/N,MAAM,CAAG,EAAG,CAE3B8N,EAAqBC,CAAY,CAAC,EAAE,CAEpC,IAAMC,EAAcD,EAAa9O,GAAG,CAClC,AAACkJ,GAAa,IACZpE,EACE,EAAA,OAAI,CAAChH,IAAI,CAACqK,EAAS,QAASe,EAAU,aACtC,OAGA8F,EAAY,MAAM9J,EAAgB6J,GAGxC,IAAK,IAAItK,EAAI,EAAGA,EAAIqK,EAAa/N,MAAM,CAAE0D,IAAK,CAC5C,IAAMoC,EAASmI,CAAS,CAACvK,EAAE,CACrBsF,EAA4B,cAAlBlD,EAAOpB,MAAM,CAAmBoB,EAAO/D,KAAK,CAAG,KAC/D,GAAIiH,EAAS,CACX,IAAMI,EAASJ,EAAQI,MAAM,CAC7B,GAAIA,GAAqC,UAA3B,OAAOA,EAAOC,QAAQ,CAAe,CACjDC,EAAqBF,EAAOC,QAAQ,CACpCyE,EAAqBC,CAAY,CAACrK,EAAE,CACpC,KACF,CACF,CACF,CACF,CACF,CAIA,GAAIgB,AAAW,cAAW,CAExB,IAAMwJ,EAAiBT,EAAiBlO,MAAM,CAC5C,AAACmI,GAAM,CAAC6F,EAAgB3M,GAAG,CAAC8G,EAAES,QAAQ,GAElCgG,EAAcD,CAAc,CAACA,EAAelO,MAAM,CAAG,EAAE,CACzDmO,GACF1D,GAAc0D,AAAqB,OADpB,UACW/F,IAAI,CAAoB,aAAe,MAAA,CAErE,CAIA,IAAe,YAAX1D,GAAmC,YAAXA,CAAW,GAAW,AAC5C6G,EAAW,CACb,IAAML,EAAS,MAAM,CAAA,EAAA,EAAA,SAAA,AAAS,GAE1BC,CADoB9K,KAAKD,GAAG,GAAK,IAAIC,KAAKkL,GAAWtJ,OAAO,GAC1CiJ,EAAO3M,gBAAgB,EAAE,CAC7CyM,GAAU,CAAA,CAEd,CAQF,MAJe,YAAXtG,GAAwB2I,EAAY,GAAK3D,GAAkB2D,IAC7DrC,GAAU,CAAA,EAGL,CAJmE,AAKxEI,MAAO,EAAA,OAAI,CAACC,QAAQ,CAACjE,aACrBgG,SACA1I,YACA2I,iBACA3D,YACA6B,EACAmC,wCACApE,qBACAwE,UACA9C,cACAP,CACF,CACF,iHC/wBA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAUA,eAAegE,EAAqBC,CAAmB,EACrD,IAAMpK,EAAoB,EAAE,CAE5B,eAAeqK,EAAKpR,CAAW,CAAEqR,CAAoB,EACnD,GAAI,CAEF,GAAqB,GAAG,CAApBF,EAAOrP,KAAK,CAEd,MAAOiP,CADS,MAAM,EAAA,QAAE,CAACjI,OAAO,CAAC9I,EAAK,CAAEgR,eAAe,CAAK,EAAA,EAEzDhP,MAAM,CAAC,AAACmI,GAAMA,EAAE8G,WAAW,IAC3BvP,GAAG,CAAC,AAACyI,GAAM,EAAA,OAAI,CAAC3K,IAAI,CAACQ,EAAKmK,EAAEkB,IAAI,GAIrC,IAAMyF,EAAW,EAAA,OAAI,CAACtR,IAAI,CAACQ,EAAK,OAAQ,QACxC,GAAI,CAEEsR,CADS,MAAM,EAAA,QAAE,CAACA,IAAI,CAACR,EAAAA,EAClBG,WAAW,IAAI,AACtBlK,EAAQ5E,IAAI,CAAC2O,EAEjB,CAAE,KAAM,CAER,CAGA,GAAIO,EAAeF,EAAOrP,KAAK,CAE7B,CAF+B,GAE1B,IAAMyP,IADK,KACIR,EADE,EAAA,IACO,IADL,CAACjI,OAAO,CAAC9I,EAAK,CAAEgR,eAAe,CAAK,EAAA,EAGxDO,EAAMN,WAAW,IACjB,CAACM,EAAMlG,IAAI,CAACmG,UAAU,CAAC,MACR,gBACf,CADAD,EAAMlG,IAAI,EAEV,MAAM+F,EAAK,EAAA,OAAI,CAAC5R,IAAI,CAACQ,EAAKuR,EAAMlG,IAAI,EAAGgG,EAAe,EAI9D,CAAE,MAAOtS,EAAK,CACP,AAAD,CAAC,EAAA,EAAA,eAAA,AAAe,EAACA,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,+BAA+B,EAAEV,EAAI,QAAQ,EAAEqR,EAAa,EAAE,CAAC,CAAEtS,EAEnF,CACF,CAEA,GAAqB,GAAG,CAApBoS,EAAOrP,KAAK,CAEd,GAAI,CAEF,MAAOiP,CADS,MAAM,EAAA,QAAE,CAACjI,OAAO,CAACqI,EAAOvP,IAAI,CAAE,CAAEoP,eAAe,CAAK,EAAA,EAEjEhP,MAAM,CAAC,AAACmI,GAAMA,EAAE8G,WAAW,IAC3BvP,GAAG,CAAC,AAACyI,GAAM,EAAA,OAAI,CAAC3K,IAAI,CAAC2R,EAAOvP,IAAI,CAAEuI,EAAEkB,IAAI,EAC7C,CAAE,MAAOtM,EAAK,CAEZ,OADA0B,QAAQC,IAAI,CAAC,CAAC,2CAA2C,EAAEyQ,EAAOvP,IAAI,CAAC,CAAC,CAAC,CAAE7C,GACpE,EACT,AADW,CAKb,OADA,MAAMqS,EAAKD,EAAOvP,IAAI,CAAE,GACjBmF,CACT,CAaA,IAAI+K,EAAkC,EAAE,CACpCC,EAAqB,EAUlB,eAAeG,IACpB,IAAMrP,EAAMC,KAAKD,GAAG,GACpB,GAAIiP,EAAerP,MAAM,CAAG,GAAKI,EAAMkP,EAXb,IAYxB,GAZ+B,IAYxBD,EAGT,IAAMnE,EAJsDqE,AAI7C,MAAM,CAAA,EAAA,EAAA,SAAS,AAAT,CAJ4D,GAK3EG,EAA2B,EAAE,CAEnC,CAlB2E,GAkBtE,IAAMhB,KAAUxD,EAAO/M,OAAO,CAAE,AACnC,GAAqB,IAAjBuQ,EAAOrP,KAAK,CAAQ,CAGtB,IAAMsQ,EAAsBjB,EAAOpP,KAAK,EAAI,EAAA,OAAI,CAAC+L,QAAQ,CAACqD,EAAOvP,IAAI,EACrE,GAAI,CAEF,IAAK,IAAM2P,IADK,KACIR,EADE,EAAA,IACO,IADL,CAACjI,OAAO,CAACqI,EAAOvP,IAAI,CAAE,CAAEoP,eAAe,CAAK,EAAA,EAElE,GAAIO,EAAMN,WAAW,GAAI,CAEvB,IAAIY,EAAcO,EAClB,GAAI,CACF,IAAMC,EAAc,EAAA,OAAI,CAAC7S,IAAI,CAAC2R,EAAOvP,IAAI,CAAE2P,EAAMlG,IAAI,CAAE,YACjDhL,EAAU,MAAM,EAAA,QAAE,CAACC,QAAQ,CAAC+R,EAAa,SACzCC,EAAO/R,KAAKC,KAAK,CAACH,GACpBiS,EAAKT,WAAW,EAAE,CACpBA,EAAcS,EAAKT,WAAAA,AAAW,CAElC,CAAE,MAAO9S,EAAK,CAEP,AAAD,CAAC,EAAA,EAAA,eAAA,AAAe,EAACA,IACnB0B,EADyB,MACjBC,IAAI,CAAC,CAAC,oCAAoC,EAAE,EAAA,OAAI,CAAClB,IAAI,CAAC2R,EAAOvP,IAAI,CAAE2P,EAAMlG,IAAI,EAAE,+BAA+B,CAAC,CAAEtM,EAE7H,CACAoT,EAAQhQ,IAAI,CAAC,CACXoQ,OAAQ,EAAA,OAAI,CAAC/S,IAAI,CAAC2R,EAAOvP,IAAI,CAAE2P,EAAMlG,IAAI,SACzC8F,cACAU,EACAD,YAAaT,EAAOvP,IAAI,AAC1B,EACF,CAEJ,CAAE,MAAO7C,EAAK,CACZ0B,QAAQC,IAAI,CAAC,CAAC,yCAAyC,EAAEyQ,EAAOvP,IAAI,CAAC,CAAC,CAAC,CAAE7C,EAC3E,CACF,MAGE,CAHK,GAGA,IAAM2S,KADM,MAAMR,AACDsB,EADsBrB,EAAAA,EACZ,CAC9B,GAAM,aAAEU,CAAW,CAAED,aAAW,CAAE,CArE1C,AAqE6CH,SArEpCA,AAAmBC,CAAe,EAGzC,IAAMC,EAAS,EAAA,OAAI,CAAC1R,OAAO,CAACyR,GACtBE,EAAc,EAAA,GADkB,IACd,CAAC3R,EADoB,KACb,CAAC0R,GAEjC,MAF0C,AAEnC,CAAEE,YADW,CADoC,CACpC,OAAI,CAAC/D,QAAQ,CAAC8D,eACZA,CAAY,CACpC,EA8DgEF,GACxD,GAAI,CAEF,IAAK,IAAMH,KADK,IACIR,EADE,EAAA,IACO,IADL,CAACjI,OAAO,CAAC4I,EAAS,CAAEV,eAAe,CAAK,EAAA,EAE1DO,EAAMN,WAAW,IAAI,AACvBkB,EAAQhQ,IAAI,CAAC,CACXoQ,OAAQ,EAAA,OAAI,CAAC/S,IAAI,CAACkS,EAASH,EAAMlG,IAAI,SACrC8F,cACAU,cACAD,CACF,EAGN,CAAE,MAAO7S,EAAK,CACZ0B,QAAQC,IAAI,CAAC,CAAC,oCAAoC,EAAEgR,EAAQ,CAAC,CAAC,CAAE3S,EAClE,CACF,CASJ,IAAM0T,EAAa,IAAIjI,IACvB,IAAK,IAAMkI,KAAOP,EAAS,CACzB,IAAMtE,EAAQ,EAAA,OAAI,CAACC,QAAQ,CAAC4E,EAAIH,MAAM,EACtC,GAAKE,CAAD,CAAYpP,GAAG,CAACwK,GAEb,CAEL,IAJ0B,AAIpBzN,EAAWqS,EAAWvH,GAAG,CAAC2C,EAE5B,CAAC8E,CADsB,MAAM,EAAA,QAAE,CAACpM,EACX,IADiB,CAAC,EAAA,OAAI,CAAC/G,IAAI,CAACY,EAASmS,MAAM,CAAE,aAAaK,IAAI,CAAC,KAAM,EAAM,KAAM,IAE5E,MAAM,EAAA,QAAE,CAACrM,MAAM,CAAC,EAAA,OAAI,CAAC/G,IAAI,CAACkT,EAAIH,MAAM,CAAE,aAAaK,IAAI,CAAC,KAAM,EAAM,KAAM,IAEpGH,EAAW9H,GAAG,CAACkD,EAAO6E,EAG5B,MAXED,EAAW9H,GAAG,CAACkD,EAAO6E,EAY1B,CAEA,IAAMnK,EAAS/G,MAAMyK,IAAI,CAACwG,EAAWvG,MAAM,IAG3C,OAFA4F,EAAiBvJ,EACjBwJ,EAAqBjP,KAAKD,GAAG,GACtB0F,CACT,CAKO,eAAeuK,IACpB,IAAMnF,EAAS,MAAM,CAAA,EAAA,EAAA,SAAA,AAAS,IACxBoF,EAAoB,EAAE,CAE5B,IAAK,IAAM5B,KAAUxD,EAAO/M,OAAO,CAAE,AACnC,GAAqB,GAAG,CAApBuQ,EAAOrP,KAAK,CAEd,GAAI,CACF,MAAM,EAAA,QAAE,CAACyE,MAAM,CAAC4K,EAAOvP,IAAI,EAC3BmR,EAAQ5Q,IAAI,CAACgP,EAAOvP,IAAI,CAC1B,CAAE,MAAO7C,EAAK,CACZ0B,QAAQC,IAAI,CAAC,CAAC,0CAA0C,EAAEyQ,EAAOvP,IAAI,CAAC,CAAC,CAAC,CAAE7C,EAC5E,KACK,CACL,IAAMyT,EAAW,MAAMtB,EAAqBC,GAC5C4B,EAAQ5Q,IAAI,IAAIqQ,EAClB,CAGF,OAAOO,CACT,4FA9HO,SAASd,EACdH,EAAiB,EAAE,CACnBC,EAAqB,CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|