@shepai/cli 1.72.9-pr220.e1bfec0 → 1.72.9-pr220.f17b60a
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/dist/packages/core/src/infrastructure/services/notifications/notification.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/notifications/notification.service.js +2 -4
- package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-feature-node-data.js +2 -26
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +2 -26
- package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +0 -2
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts +2 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.js +11 -11
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +17 -27
- package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts +0 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/index.js +0 -1
- package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts +25 -0
- package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +45 -2
- package/dist/src/presentation/web/components/common/index.d.ts +1 -2
- package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/index.js +1 -2
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +3 -4
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +46 -58
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -13
- package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/alert-dialog.js +2 -2
- package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/dialog.js +2 -2
- package/dist/src/presentation/web/hooks/use-agent-events.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-agent-events.js +6 -3
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts +2 -1
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.js +50 -23
- package/dist/src/presentation/web/hooks/use-notifications.d.ts +1 -5
- package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-notifications.js +1 -26
- package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-notifications.stories.js +28 -38
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +15 -15
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +15 -15
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
- package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_250a63ae._.js +1 -1
- package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_63688261._.js → _8e87c87b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_63688261._.js.map → _8e87c87b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +21 -21
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +18 -18
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +18 -18
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +13 -13
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +13 -13
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_250a63ae._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_63688261._.js → _8e87c87b._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +21 -21
- package/web/.next/standalone/src/presentation/web/app/build-feature-node-data.ts +3 -30
- package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +3 -30
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +0 -2
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/drawer-view.ts +12 -13
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +21 -37
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/index.ts +0 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +63 -2
- package/web/.next/standalone/src/presentation/web/components/common/index.ts +1 -7
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +12 -21
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +65 -70
- package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +1 -18
- package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +2 -5
- package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +2 -5
- package/web/.next/standalone/src/presentation/web/hooks/use-agent-events.ts +7 -3
- package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +104 -71
- package/web/.next/standalone/src/presentation/web/hooks/use-notifications.stories.tsx +2 -30
- package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +2 -36
- package/web/.next/static/chunks/0ffccd7be73305c8.css +2 -0
- package/web/.next/static/chunks/3f205fd6adbfd20a.js +7 -0
- package/web/.next/static/chunks/76827713cb2b7333.js +1 -0
- package/web/.next/static/chunks/{c575ab63c138645b.js → 792aac476adb5875.js} +1 -1
- package/web/.next/static/chunks/7c8adcfd920a8f74.js +1 -0
- package/web/.next/static/chunks/{cdc92cdf81005c84.js → 83463b63971f5723.js} +1 -1
- package/web/.next/static/chunks/{63a80e9d4c4b0253.js → 98ca891a5c156aa5.js} +3 -3
- package/web/.next/static/chunks/{638824249d103905.js → 9b1770f05f1d95e5.js} +1 -1
- package/web/.next/static/chunks/a7f52757dff0cea0.js +1 -0
- package/web/.next/static/chunks/b6becf0de992842a.js +1 -0
- package/web/.next/static/chunks/{f32c98a709949c5b.js → cb41849bcfaa304e.js} +1 -1
- package/web/.next/static/chunks/d5e95c4482029a39.js +1 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts +0 -12
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js +0 -337
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts +0 -33
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.js +0 -214
- package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts +0 -2
- package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/notification-permission-banner/index.js +0 -1
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts +0 -2
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.js +0 -33
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts +0 -6
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.js +0 -24
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx +0 -293
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx +0 -745
- package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/index.ts +0 -1
- package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.tsx +0 -52
- package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.tsx +0 -55
- package/web/.next/static/chunks/0a883e2efecfd563.js +0 -1
- package/web/.next/static/chunks/0c54314c8c9c9739.js +0 -7
- package/web/.next/static/chunks/596ca28d78baae25.js +0 -1
- package/web/.next/static/chunks/71c9ecdceac1939f.css +0 -2
- package/web/.next/static/chunks/a040b058d79f4ade.js +0 -1
- package/web/.next/static/chunks/e05eb1cc84ee254a.js +0 -1
- package/web/.next/static/chunks/ef8f8940eac6c542.js +0 -1
- /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_buildManifest.js +0 -0
- /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{uMxPSDPwZCludF5408rWJ → eg0FTlsA4z_7CXbFfMgAr}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useMemo
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
4
|
import { ReactFlow, Background, Controls } from '@xyflow/react';
|
|
5
5
|
import type { Connection, Edge, NodeChange } from '@xyflow/react';
|
|
6
6
|
import { Plus } from 'lucide-react';
|
|
@@ -56,22 +56,6 @@ export function FeaturesCanvas({
|
|
|
56
56
|
[]
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
-
// Prevent a feature from having more than one source repository
|
|
60
|
-
const isValidConnection = useCallback(
|
|
61
|
-
(connection: Edge | Connection) => {
|
|
62
|
-
const sourceNode = nodes.find((n) => n.id === connection.source);
|
|
63
|
-
if (sourceNode?.type !== 'repositoryNode') return true;
|
|
64
|
-
|
|
65
|
-
const targetAlreadyHasRepo = edges.some((e) => {
|
|
66
|
-
const edgeSourceNode = nodes.find((n) => n.id === e.source);
|
|
67
|
-
return edgeSourceNode?.type === 'repositoryNode' && e.target === connection.target;
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return !targetAlreadyHasRepo;
|
|
71
|
-
},
|
|
72
|
-
[nodes, edges]
|
|
73
|
-
);
|
|
74
|
-
|
|
75
59
|
// Callbacks and showHandles are already injected into node.data by deriveGraph.
|
|
76
60
|
// Only selectedFeatureId highlighting needs to be applied here.
|
|
77
61
|
const enrichedNodes = useMemo(
|
|
@@ -122,7 +106,6 @@ export function FeaturesCanvas({
|
|
|
122
106
|
edges={edges}
|
|
123
107
|
nodeTypes={nodeTypes}
|
|
124
108
|
edgeTypes={edgeTypes}
|
|
125
|
-
isValidConnection={isValidConnection}
|
|
126
109
|
onConnect={onConnect}
|
|
127
110
|
onNodesChange={onNodesChange}
|
|
128
111
|
onNodeClick={onNodeClick}
|
|
@@ -28,10 +28,7 @@ function AlertDialogOverlay({
|
|
|
28
28
|
return (
|
|
29
29
|
<AlertDialogPrimitive.Overlay
|
|
30
30
|
data-slot="alert-dialog-overlay"
|
|
31
|
-
className={cn(
|
|
32
|
-
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
|
|
33
|
-
className
|
|
34
|
-
)}
|
|
31
|
+
className={cn('fixed inset-0 z-50 bg-black/50', className)}
|
|
35
32
|
onClick={(e) => {
|
|
36
33
|
// Prevent overlay clicks from propagating to document-level handlers
|
|
37
34
|
// (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
|
|
@@ -57,7 +54,7 @@ function AlertDialogContent({
|
|
|
57
54
|
data-slot="alert-dialog-content"
|
|
58
55
|
data-size={size}
|
|
59
56
|
className={cn(
|
|
60
|
-
'bg-background
|
|
57
|
+
'bg-background group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg',
|
|
61
58
|
className
|
|
62
59
|
)}
|
|
63
60
|
{...props}
|
|
@@ -20,10 +20,7 @@ const DialogOverlay = React.forwardRef<
|
|
|
20
20
|
>(({ className, onClick, ...props }, ref) => (
|
|
21
21
|
<DialogPrimitive.Overlay
|
|
22
22
|
ref={ref}
|
|
23
|
-
className={cn(
|
|
24
|
-
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
|
|
25
|
-
className
|
|
26
|
-
)}
|
|
23
|
+
className={cn('fixed inset-0 z-50 bg-black/80', className)}
|
|
27
24
|
onClick={(e) => {
|
|
28
25
|
// Prevent overlay clicks from propagating to document-level handlers
|
|
29
26
|
// (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
|
|
@@ -44,7 +41,7 @@ const DialogContent = React.forwardRef<
|
|
|
44
41
|
<DialogPrimitive.Content
|
|
45
42
|
ref={ref}
|
|
46
43
|
className={cn(
|
|
47
|
-
'bg-background
|
|
44
|
+
'bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg',
|
|
48
45
|
className
|
|
49
46
|
)}
|
|
50
47
|
{...props}
|
|
@@ -103,9 +103,13 @@ export function useAgentEvents(options?: UseAgentEventsOptions): UseAgentEventsR
|
|
|
103
103
|
if (sw.state === 'activated') {
|
|
104
104
|
subscribeToWorker(sw);
|
|
105
105
|
} else {
|
|
106
|
-
|
|
107
|
-
if (sw.state === 'activated')
|
|
108
|
-
|
|
106
|
+
const onStateChange = () => {
|
|
107
|
+
if (sw.state === 'activated') {
|
|
108
|
+
sw.removeEventListener('statechange', onStateChange);
|
|
109
|
+
subscribeToWorker(sw);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
sw.addEventListener('statechange', onStateChange);
|
|
109
113
|
}
|
|
110
114
|
})
|
|
111
115
|
.catch(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useMemo, useCallback, useRef } from 'react';
|
|
4
|
-
import type { Edge } from '@xyflow/react';
|
|
4
|
+
import type { Edge, Position } from '@xyflow/react';
|
|
5
5
|
import type { CanvasNodeType } from '@/components/features/features-canvas';
|
|
6
6
|
import type { FeatureNodeData } from '@/components/common/feature-node';
|
|
7
7
|
import type { RepositoryNodeData } from '@/components/common/repository-node';
|
|
@@ -26,10 +26,7 @@ export interface UseGraphStateReturn {
|
|
|
26
26
|
*/
|
|
27
27
|
reconcile: (newNodes: CanvasNodeType[], newEdges: Edge[]) => void;
|
|
28
28
|
/** Update a feature's state/lifecycle/name (e.g., from SSE events). */
|
|
29
|
-
updateFeature: (
|
|
30
|
-
featureNodeId: string,
|
|
31
|
-
updates: Partial<Pick<FeatureNodeData, 'state' | 'lifecycle' | 'name' | 'description'>>
|
|
32
|
-
) => void;
|
|
29
|
+
updateFeature: (featureNodeId: string, updates: FeatureDataUpdates) => void;
|
|
33
30
|
/** Add a pending (optimistic) feature node (state='creating'). */
|
|
34
31
|
addPendingFeature: (nodeId: string, data: FeatureNodeData, parentNodeId?: string) => void;
|
|
35
32
|
/** Remove a pending feature node (e.g., on rollback). */
|
|
@@ -63,7 +60,7 @@ function parseMaps(
|
|
|
63
60
|
// Build parentNodeId map from dependency edges
|
|
64
61
|
const parentByChild = new Map<string, string>();
|
|
65
62
|
for (const edge of initialEdges) {
|
|
66
|
-
if (edge.type === 'dependencyEdge'
|
|
63
|
+
if (edge.type === 'dependencyEdge') {
|
|
67
64
|
parentByChild.set(edge.target, edge.source);
|
|
68
65
|
}
|
|
69
66
|
}
|
|
@@ -89,6 +86,19 @@ function parseMaps(
|
|
|
89
86
|
return { featureMap, repoMap };
|
|
90
87
|
}
|
|
91
88
|
|
|
89
|
+
type FeatureDataUpdates = Partial<
|
|
90
|
+
Pick<FeatureNodeData, 'state' | 'lifecycle' | 'name' | 'description'>
|
|
91
|
+
>;
|
|
92
|
+
|
|
93
|
+
function isFeatureDataUnchanged(data: FeatureNodeData, updates: FeatureDataUpdates): boolean {
|
|
94
|
+
return (
|
|
95
|
+
(updates.state === undefined || updates.state === data.state) &&
|
|
96
|
+
(updates.lifecycle === undefined || updates.lifecycle === data.lifecycle) &&
|
|
97
|
+
(updates.name === undefined || updates.name === data.name) &&
|
|
98
|
+
(updates.description === undefined || updates.description === data.description)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
export function useGraphState(
|
|
93
103
|
initialNodes: CanvasNodeType[],
|
|
94
104
|
initialEdges: Edge[]
|
|
@@ -129,17 +139,69 @@ export function useGraphState(
|
|
|
129
139
|
const repoMapRef = useRef(repoMap);
|
|
130
140
|
repoMapRef.current = repoMap;
|
|
131
141
|
|
|
132
|
-
//
|
|
142
|
+
// Derive graph from domain Maps (runs on every Map change, but dagre only on topology change)
|
|
143
|
+
const derived = useMemo(
|
|
144
|
+
() => deriveGraph(featureMap, repoMap, pendingMap, stableCallbacks),
|
|
145
|
+
[featureMap, repoMap, pendingMap, stableCallbacks]
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Cache dagre layout positions — only re-run when node set or edge connections change
|
|
149
|
+
const layoutCacheRef = useRef<{
|
|
150
|
+
key: string;
|
|
151
|
+
positions: Map<
|
|
152
|
+
string,
|
|
153
|
+
{ position: { x: number; y: number }; targetPosition: Position; sourcePosition: Position }
|
|
154
|
+
>;
|
|
155
|
+
}>({ key: '', positions: new Map() });
|
|
156
|
+
|
|
133
157
|
const { nodes, edges } = useMemo(() => {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
158
|
+
const nodeIds = derived.nodes
|
|
159
|
+
.map((n) => n.id)
|
|
160
|
+
.sort()
|
|
161
|
+
.join(',');
|
|
162
|
+
const edgeKeys = derived.edges
|
|
163
|
+
.map((e) => `${e.source}-${e.target}`)
|
|
164
|
+
.sort()
|
|
165
|
+
.join(',');
|
|
166
|
+
const topologyKey = `${nodeIds}|${edgeKeys}`;
|
|
167
|
+
|
|
168
|
+
if (topologyKey !== layoutCacheRef.current.key) {
|
|
169
|
+
// Topology changed — re-run dagre
|
|
170
|
+
const result = layoutWithDagre(derived.nodes, derived.edges, CANVAS_LAYOUT_DEFAULTS);
|
|
171
|
+
const positions = new Map<
|
|
172
|
+
string,
|
|
173
|
+
{ position: { x: number; y: number }; targetPosition: Position; sourcePosition: Position }
|
|
174
|
+
>();
|
|
175
|
+
for (const node of result.nodes) {
|
|
176
|
+
positions.set(node.id, {
|
|
177
|
+
position: node.position,
|
|
178
|
+
targetPosition: (node as Record<string, unknown>).targetPosition as Position,
|
|
179
|
+
sourcePosition: (node as Record<string, unknown>).sourcePosition as Position,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
layoutCacheRef.current = { key: topologyKey, positions };
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Data-only change — apply cached positions without re-running dagre
|
|
187
|
+
const { positions } = layoutCacheRef.current;
|
|
188
|
+
const nodes = derived.nodes.map((node) => {
|
|
189
|
+
const cached = positions.get(node.id);
|
|
190
|
+
return cached ? { ...node, ...cached } : node;
|
|
191
|
+
});
|
|
192
|
+
return { nodes, edges: derived.edges };
|
|
193
|
+
}, [derived]);
|
|
137
194
|
|
|
138
195
|
// --- Mutations ---
|
|
139
196
|
|
|
140
197
|
const reconcile = useCallback((newNodes: CanvasNodeType[], newEdges: Edge[]) => {
|
|
141
198
|
const { featureMap: newFeatureMap, repoMap: newRepoMap } = parseMaps(newNodes, newEdges);
|
|
142
199
|
|
|
200
|
+
// Precompute match keys so we don't scan newFeatureMap.values() per pending entry
|
|
201
|
+
const realFeatureKeys = new Set(
|
|
202
|
+
[...newFeatureMap.values()].map((e) => `${e.data.name}\0${e.data.repositoryPath}`)
|
|
203
|
+
);
|
|
204
|
+
|
|
143
205
|
setFeatureMap((currentFeatureMap) => {
|
|
144
206
|
// Preserve pending (creating) nodes unless matched by name+repositoryPath from newFeatureMap
|
|
145
207
|
const pendingEntries = [...currentFeatureMap.entries()].filter(
|
|
@@ -150,12 +212,8 @@ export function useGraphState(
|
|
|
150
212
|
|
|
151
213
|
// Keep pending nodes that don't have a real counterpart in new data
|
|
152
214
|
for (const [tempId, pendingEntry] of pendingEntries) {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
e.data.name === pendingEntry.data.name &&
|
|
156
|
-
e.data.repositoryPath === pendingEntry.data.repositoryPath
|
|
157
|
-
);
|
|
158
|
-
if (!matched) {
|
|
215
|
+
const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
|
|
216
|
+
if (!realFeatureKeys.has(key)) {
|
|
159
217
|
merged.set(tempId, pendingEntry);
|
|
160
218
|
}
|
|
161
219
|
}
|
|
@@ -178,12 +236,8 @@ export function useGraphState(
|
|
|
178
236
|
let changed = false;
|
|
179
237
|
const next = new Map(currentPendingMap);
|
|
180
238
|
for (const [tempId, pendingEntry] of currentPendingMap) {
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
e.data.name === pendingEntry.data.name &&
|
|
184
|
-
e.data.repositoryPath === pendingEntry.data.repositoryPath
|
|
185
|
-
);
|
|
186
|
-
if (matched) {
|
|
239
|
+
const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
|
|
240
|
+
if (realFeatureKeys.has(key)) {
|
|
187
241
|
next.delete(tempId);
|
|
188
242
|
changed = true;
|
|
189
243
|
}
|
|
@@ -194,56 +248,35 @@ export function useGraphState(
|
|
|
194
248
|
setRepoMap(newRepoMap);
|
|
195
249
|
}, []);
|
|
196
250
|
|
|
197
|
-
const updateFeature = useCallback(
|
|
198
|
-
(
|
|
199
|
-
featureNodeId
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const stateUnchanged = updates.state === undefined || updates.state === entry.data.state;
|
|
216
|
-
const lifecycleUnchanged =
|
|
217
|
-
updates.lifecycle === undefined || updates.lifecycle === entry.data.lifecycle;
|
|
218
|
-
const nameUnchanged = updates.name === undefined || updates.name === entry.data.name;
|
|
219
|
-
const descUnchanged =
|
|
220
|
-
updates.description === undefined || updates.description === entry.data.description;
|
|
221
|
-
if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged) {
|
|
222
|
-
return prev;
|
|
223
|
-
}
|
|
224
|
-
const next = new Map(prev);
|
|
225
|
-
next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
|
|
226
|
-
return next;
|
|
227
|
-
});
|
|
251
|
+
const updateFeature = useCallback((featureNodeId: string, updates: FeatureDataUpdates) => {
|
|
252
|
+
setFeatureMap((prev) => {
|
|
253
|
+
const entry = prev.get(featureNodeId);
|
|
254
|
+
if (!entry) {
|
|
255
|
+
// Feature not yet in map — buffer update for when reconcile adds it
|
|
256
|
+
pendingUpdatesRef.current.set(featureNodeId, {
|
|
257
|
+
...pendingUpdatesRef.current.get(featureNodeId),
|
|
258
|
+
...updates,
|
|
259
|
+
});
|
|
260
|
+
return prev;
|
|
261
|
+
}
|
|
262
|
+
// Clear any buffered update for this feature since it's now in the map
|
|
263
|
+
pendingUpdatesRef.current.delete(featureNodeId);
|
|
264
|
+
if (isFeatureDataUnchanged(entry.data, updates)) return prev;
|
|
265
|
+
const next = new Map(prev);
|
|
266
|
+
next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
|
|
267
|
+
return next;
|
|
268
|
+
});
|
|
228
269
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged) return prev;
|
|
240
|
-
const next = new Map(prev);
|
|
241
|
-
next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
|
|
242
|
-
return next;
|
|
243
|
-
});
|
|
244
|
-
},
|
|
245
|
-
[]
|
|
246
|
-
);
|
|
270
|
+
// Also check pendingMap
|
|
271
|
+
setPendingMap((prev) => {
|
|
272
|
+
const entry = prev.get(featureNodeId);
|
|
273
|
+
if (!entry) return prev;
|
|
274
|
+
if (isFeatureDataUnchanged(entry.data, updates)) return prev;
|
|
275
|
+
const next = new Map(prev);
|
|
276
|
+
next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
|
|
277
|
+
return next;
|
|
278
|
+
});
|
|
279
|
+
}, []);
|
|
247
280
|
|
|
248
281
|
const addPendingFeature = useCallback(
|
|
249
282
|
(nodeId: string, data: FeatureNodeData, parentNodeId?: string) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useMemo
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { toast } from 'sonner';
|
|
4
4
|
import { Toaster } from '@/components/ui/sonner';
|
|
@@ -44,45 +44,17 @@ function NotificationDemo() {
|
|
|
44
44
|
const method = event.severity ?? 'info';
|
|
45
45
|
toast[method](event.featureName, { description: event.message });
|
|
46
46
|
|
|
47
|
-
if (globalThis.Notification?.permission === 'granted') {
|
|
48
|
-
new Notification(event.featureName, { body: event.message });
|
|
49
|
-
}
|
|
50
|
-
|
|
51
47
|
const soundName = SEVERITY_SOUNDS[event.severity];
|
|
52
48
|
soundsByName[soundName]?.play();
|
|
53
49
|
},
|
|
54
50
|
[soundsByName]
|
|
55
51
|
);
|
|
56
52
|
|
|
57
|
-
const [browserPermission, setBrowserPermission] = useState<NotificationPermission>(
|
|
58
|
-
typeof globalThis.Notification !== 'undefined' ? globalThis.Notification.permission : 'default'
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
const requestPermission = async () => {
|
|
62
|
-
if (typeof globalThis.Notification === 'undefined') return;
|
|
63
|
-
const result = await globalThis.Notification.requestPermission();
|
|
64
|
-
setBrowserPermission(result);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
53
|
return (
|
|
68
54
|
<div className="flex w-[420px] flex-col gap-6">
|
|
69
|
-
<div className="flex flex-col gap-2">
|
|
70
|
-
<h3 className="text-sm font-semibold">Browser Notification Permission</h3>
|
|
71
|
-
<div className="flex items-center gap-3">
|
|
72
|
-
<span className="text-muted-foreground text-sm">
|
|
73
|
-
Status: <code className="bg-muted rounded px-1.5 py-0.5">{browserPermission}</code>
|
|
74
|
-
</span>
|
|
75
|
-
<Button size="sm" variant="outline" onClick={requestPermission}>
|
|
76
|
-
Request Permission
|
|
77
|
-
</Button>
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
55
|
<div className="flex flex-col gap-2">
|
|
82
56
|
<h3 className="text-sm font-semibold">Simulate Notification Events</h3>
|
|
83
|
-
<p className="text-muted-foreground text-xs">
|
|
84
|
-
Click a button to fire a toast, browser notification, and sound.
|
|
85
|
-
</p>
|
|
57
|
+
<p className="text-muted-foreground text-xs">Click a button to fire a toast and sound.</p>
|
|
86
58
|
<div className="flex flex-wrap gap-2">
|
|
87
59
|
<Button
|
|
88
60
|
size="sm"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { useRouter } from 'next/navigation';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
6
|
import type { NotificationEvent } from '@shepai/core/domain/generated/output';
|
|
@@ -9,11 +9,6 @@ import { useAgentEventsContext } from './agent-events-provider';
|
|
|
9
9
|
import { useSoundAction } from './use-sound-action';
|
|
10
10
|
import type { SoundAction } from './use-sound-action';
|
|
11
11
|
|
|
12
|
-
export interface UseNotificationsResult {
|
|
13
|
-
requestBrowserPermission: () => Promise<void>;
|
|
14
|
-
browserPermissionState: NotificationPermission;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
12
|
const SEVERITY_TO_TOAST: Record<NotificationSeverity, 'success' | 'error' | 'warning' | 'info'> = {
|
|
18
13
|
[NotificationSeverity.Success]: 'success',
|
|
19
14
|
[NotificationSeverity.Error]: 'error',
|
|
@@ -38,16 +33,6 @@ function dispatchToast(event: NotificationEvent, navigate?: (path: string) => vo
|
|
|
38
33
|
});
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
function dispatchBrowserNotification(event: NotificationEvent): void {
|
|
42
|
-
if (globalThis.Notification?.permission !== 'granted') {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
new Notification(`Shep: ${event.featureName}`, {
|
|
46
|
-
body: event.message,
|
|
47
|
-
icon: '/favicon-light.svg',
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
36
|
const SEVERITY_TO_ACTION: Record<NotificationSeverity, SoundAction> = {
|
|
52
37
|
[NotificationSeverity.Success]: 'notification-success',
|
|
53
38
|
[NotificationSeverity.Error]: 'notification-error',
|
|
@@ -55,7 +40,7 @@ const SEVERITY_TO_ACTION: Record<NotificationSeverity, SoundAction> = {
|
|
|
55
40
|
[NotificationSeverity.Info]: 'notification-info',
|
|
56
41
|
};
|
|
57
42
|
|
|
58
|
-
export function useNotifications():
|
|
43
|
+
export function useNotifications(): void {
|
|
59
44
|
const router = useRouter();
|
|
60
45
|
const { events } = useAgentEventsContext();
|
|
61
46
|
|
|
@@ -74,13 +59,6 @@ export function useNotifications(): UseNotificationsResult {
|
|
|
74
59
|
[successSound, errorSound, warningSound, infoSound]
|
|
75
60
|
);
|
|
76
61
|
|
|
77
|
-
const [browserPermissionState, setBrowserPermissionState] = useState<NotificationPermission>(
|
|
78
|
-
() => {
|
|
79
|
-
if (typeof globalThis.Notification === 'undefined') return 'default';
|
|
80
|
-
return globalThis.Notification.permission;
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
|
|
84
62
|
// Track how many events from the array we've already processed.
|
|
85
63
|
// Using the array index (instead of lastEvent) prevents React batching
|
|
86
64
|
// from silently dropping events when multiple SSE messages arrive together.
|
|
@@ -103,21 +81,9 @@ export function useNotifications(): UseNotificationsResult {
|
|
|
103
81
|
}
|
|
104
82
|
|
|
105
83
|
dispatchToast(event, (path) => router.push(path as Parameters<typeof router.push>[0]));
|
|
106
|
-
dispatchBrowserNotification(event);
|
|
107
84
|
|
|
108
85
|
const actionName = SEVERITY_TO_ACTION[event.severity];
|
|
109
86
|
soundsByAction[actionName]?.play();
|
|
110
87
|
}
|
|
111
88
|
}, [events, soundsByAction, router]);
|
|
112
|
-
|
|
113
|
-
const requestBrowserPermission = useCallback(async () => {
|
|
114
|
-
if (typeof globalThis.Notification === 'undefined') return;
|
|
115
|
-
const result = await globalThis.Notification.requestPermission();
|
|
116
|
-
setBrowserPermissionState(result);
|
|
117
|
-
}, []);
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
requestBrowserPermission,
|
|
121
|
-
browserPermissionState,
|
|
122
|
-
};
|
|
123
89
|
}
|