@shepai/cli 1.122.1 → 1.122.2-pr367.fdba557
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/application/ports/output/services/index.d.ts +2 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts +41 -0
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/tunnel-service.interface.js +14 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts +65 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/webhook-service.interface.js +10 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +14 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +21 -4
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts +7 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/validate.node.js +24 -2
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts +55 -0
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/tunnel/cloudflare-tunnel.service.js +203 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts +75 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/webhook/github-webhook.service.js +372 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts +82 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/webhook/webhook-manager.service.js +206 -0
- package/dist/src/presentation/cli/commands/ui.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/ui.command.js +15 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts +3 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/load-webhook-status.js +19 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts +9 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/deliveries/route.js +27 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts +17 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/github/route.js +70 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts +9 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/webhooks/status/route.js +26 -0
- package/dist/src/presentation/web/app/webhooks/page.d.ts +4 -0
- package/dist/src/presentation/web/app/webhooks/page.d.ts.map +1 -0
- package/dist/src/presentation/web/app/webhooks/page.js +9 -0
- package/dist/src/presentation/web/components/features/webhooks/types.d.ts +32 -0
- package/dist/src/presentation/web/components/features/webhooks/types.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/types.js +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.js +38 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.js +69 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts +7 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.js +11 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.js +31 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.js +21 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.js +56 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts +6 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.js +39 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts +8 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/webhooks/webhooks-page-client.stories.js +59 -0
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
- package/dist/src/presentation/web/dev-server.js +20 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +5 -1
- package/web/.next/build-manifest.json +6 -6
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/routes-manifest.json +24 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
- 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]/[tab]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
- package/web/.next/server/app/(dashboard)/create/page.js +1 -1
- 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]/[tab]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
- 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/page/build-manifest.json +4 -4
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page.js +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/webhooks/deliveries/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/deliveries/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/deliveries/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js +6 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/deliveries/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/deliveries/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/webhooks/github/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/github/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/github/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/github/route.js +6 -0
- package/web/.next/server/app/api/webhooks/github/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/github/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/github/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/webhooks/status/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/webhooks/status/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/webhooks/status/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/webhooks/status/route.js +6 -0
- package/web/.next/server/app/api/webhooks/status/route.js.map +5 -0
- package/web/.next/server/app/api/webhooks/status/route.js.nft.json +1 -0
- package/web/.next/server/app/api/webhooks/status/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/build-manifest.json +4 -4
- package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/settings/page.js +1 -1
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/build-manifest.json +4 -4
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js +1 -1
- 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/build-manifest.json +4 -4
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js +2 -2
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/webhooks/page/app-paths-manifest.json +3 -0
- package/web/.next/server/app/webhooks/page/build-manifest.json +18 -0
- package/web/.next/server/app/webhooks/page/next-font-manifest.json +6 -0
- package/web/.next/server/app/webhooks/page/react-loadable-manifest.json +1 -0
- package/web/.next/server/app/webhooks/page/server-reference-manifest.json +35 -0
- package/web/.next/server/app/webhooks/page.js +16 -0
- package/web/.next/server/app/webhooks/page.js.map +5 -0
- package/web/.next/server/app/webhooks/page.js.nft.json +1 -0
- package/web/.next/server/app/webhooks/page_client-reference-manifest.js +2 -0
- package/web/.next/server/app-paths-manifest.json +5 -1
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_deliveries_route_actions_d9e34c8d.js.map +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_github_route_actions_1b0d0c38.js.map +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_webhooks_status_route_actions_1a0d86a1.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__15e5d45c._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__23be381e._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js → [root-of-the-server]__3baec744._.js} +2 -2
- package/web/.next/server/chunks/{[root-of-the-server]__42b7ab55._.js.map → [root-of-the-server]__3baec744._.js.map} +1 -1
- package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js → [root-of-the-server]__7d63f9a4._.js} +2 -2
- package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__9fc760c0._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js → [root-of-the-server]__a1c7c02a._.js} +2 -2
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.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/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_activity_22f9667f.js.map +1 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +1 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__6b17a22d._.js.map → [root-of-the-server]__11033878._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js → [root-of-the-server]__12c2ab7d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__06fef644._.js.map → [root-of-the-server]__12c2ab7d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3c16bf85._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__610f06df._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__76915230._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__8c553503._.js.map → [root-of-the-server]__76915230._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7a939e4e._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a022445f._.js.map → [root-of-the-server]__7a939e4e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87a7ae30._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__920dccd5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c4dc1b5a._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__a7de2711._.js.map → [root-of-the-server]__c4dc1b5a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +4 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__804c006d._.js.map → [root-of-the-server]__fdc75809._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_07f57bd0._.js +3 -0
- package/web/.next/server/chunks/ssr/_07f57bd0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_15a756dd._.js +3 -0
- package/web/.next/server/chunks/ssr/_15a756dd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_26b2c311._.js +3 -0
- package/web/.next/server/chunks/ssr/_26b2c311._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_92d851b4._.js → _3d1ed2a7._.js} +2 -2
- package/web/.next/server/chunks/ssr/_3d1ed2a7._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_3eca2297._.js +3 -0
- package/web/.next/server/chunks/ssr/{_b294a667._.js.map → _3eca2297._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_4470c218._.js +3 -0
- package/web/.next/server/chunks/ssr/_4470c218._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_462cc3a6._.js +3 -0
- package/web/.next/server/chunks/ssr/_462cc3a6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_961cb4b2._.js +3 -0
- package/web/.next/server/chunks/ssr/_961cb4b2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_a4899a76._.js +3 -0
- package/web/.next/server/chunks/ssr/_a4899a76._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_b5babdfc._.js +9 -0
- package/web/.next/server/chunks/ssr/_b5babdfc._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_b7eb93fc._.js +4 -0
- package/web/.next/server/chunks/ssr/_b7eb93fc._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f8b36e2c._.js +3 -0
- package/web/.next/server/chunks/ssr/_f8b36e2c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js +3 -0
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_webhooks_webhooks-page-client_tsx_b2662ea3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_1bb131c4._.js → node_modules__pnpm_747b43ac._.js} +2 -2
- package/web/.next/server/chunks/ssr/node_modules__pnpm_747b43ac._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +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/middleware-build-manifest.js +4 -4
- 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 +57 -35
- package/web/.next/static/chunks/0c76de69325ef923.js +1 -0
- package/web/.next/static/chunks/{658fc2f5f65cf3b5.js → 1b9d34af4064dafe.js} +2 -2
- package/web/.next/static/chunks/{50dd80c8aafa3b20.js → 293ccfbe777d995a.js} +1 -1
- package/web/.next/static/chunks/3835a408dbf8d0bb.js +1 -0
- package/web/.next/static/chunks/{941c13dcdb1978a4.js → 3f0773d9b56e04a2.js} +2 -2
- package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +1 -0
- package/web/.next/static/chunks/4c5b31a2c65d4aa5.js +11 -0
- package/web/.next/static/chunks/59a0709f1b080353.js +1 -0
- package/web/.next/static/chunks/5f6161ceb4263319.js +1 -0
- package/web/.next/static/chunks/77ff1b7b725b7780.js +1 -0
- package/web/.next/static/chunks/{672e3da3ad26005b.js → 98e3a7cf58fc912a.js} +1 -1
- package/web/.next/static/chunks/9af45e885bd4ccef.js +1 -0
- package/web/.next/static/chunks/a57dc2afcf67304a.js +1 -0
- package/web/.next/static/chunks/b4f502a76ba10e4b.js +1 -0
- package/web/.next/static/chunks/b5d8e8100e310d9f.css +1 -0
- package/web/.next/static/chunks/{df85e52b1afb7340.js → b747e59ebdcbd917.js} +1 -1
- package/web/.next/static/chunks/c04ce6760f349f3e.js +1 -0
- package/web/.next/static/chunks/{78ab7b134f0649ac.js → c3c68de2392a9071.js} +1 -1
- package/web/.next/static/chunks/c7e793951b20a67f.js +1 -0
- package/web/.next/static/chunks/cf30e300568abf0f.js +1 -0
- package/web/.next/static/chunks/d43dff89384fb60a.js +1 -0
- package/web/.next/static/chunks/{37ac7fe1cd493293.js → e087f3e5c46c0756.js} +1 -1
- package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-b1685b5f87ad1d60.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +0 -4
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +0 -3
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_1bb131c4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_1bb79fe8._.js +0 -3
- package/web/.next/server/chunks/ssr/_1bb79fe8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_469c5451._.js +0 -3
- package/web/.next/server/chunks/ssr/_469c5451._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_6d26a08f._.js +0 -3
- package/web/.next/server/chunks/ssr/_6d26a08f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js +0 -3
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_92d851b4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_b294a667._.js +0 -3
- package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
- package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f1a649e3._.js +0 -9
- package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_b59e4b16._.js.map +0 -1
- package/web/.next/static/chunks/0d2af96e64960ef5.css +0 -1
- package/web/.next/static/chunks/11e4439096f8d652.js +0 -1
- package/web/.next/static/chunks/303a1217006489b9.js +0 -1
- package/web/.next/static/chunks/4562ee849ea13c3a.js +0 -1
- package/web/.next/static/chunks/845d8e58a91014e6.js +0 -1
- package/web/.next/static/chunks/84a181ff3270fd9f.js +0 -1
- package/web/.next/static/chunks/96eeeb28e06de78c.js +0 -1
- package/web/.next/static/chunks/9df4681de92ebfc3.js +0 -11
- package/web/.next/static/chunks/cca0f5112a9260d8.js +0 -1
- package/web/.next/static/chunks/e2ef95d904c360f3.js +0 -1
- package/web/.next/static/chunks/e6a2fb8707e079ff.js +0 -1
- package/web/.next/static/chunks/e9c3fbbeb418cbfa.js +0 -1
- package/web/.next/static/chunks/ed3a602003bcb31b.js +0 -1
- /package/web/.next/server/chunks/{[root-of-the-server]__53013576._.js.map → [root-of-the-server]__7d63f9a4._.js.map} +0 -0
- /package/web/.next/server/chunks/{[root-of-the-server]__92078db6._.js.map → [root-of-the-server]__a1c7c02a._.js.map} +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_buildManifest.js +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{hsK1x0unrjI_pUsvQhn6P → svtG6xX1MdaGWkml8eX53}/_ssgManifest.js +0 -0
|
@@ -23,6 +23,7 @@ import { initializeNotificationWatcher, getNotificationWatcher, } from '../../..
|
|
|
23
23
|
import { initializePrSyncWatcher, getPrSyncWatcher, } from '../../../../packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js';
|
|
24
24
|
import { getExistingConnection } from '../../../../packages/core/src/infrastructure/persistence/sqlite/connection.js';
|
|
25
25
|
import { BrowserOpenerService } from '../../../../packages/core/src/infrastructure/services/browser-opener.service.js';
|
|
26
|
+
import { initializeWebhookManager, getWebhookManager, hasWebhookManager, } from '../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
|
|
26
27
|
import { colors, fmt, messages } from '../ui/index.js';
|
|
27
28
|
function parsePort(value) {
|
|
28
29
|
const port = parseInt(value, 10);
|
|
@@ -70,6 +71,17 @@ Examples:
|
|
|
70
71
|
const db = getExistingConnection();
|
|
71
72
|
initializePrSyncWatcher(featureRepo, runRepo, gitPrService, notificationService, undefined, db);
|
|
72
73
|
getPrSyncWatcher().start();
|
|
74
|
+
// Start webhook system (optional — falls back to polling if cloudflared is not available)
|
|
75
|
+
try {
|
|
76
|
+
const tunnelService = container.resolve('ITunnelService');
|
|
77
|
+
const webhookService = container.resolve('IWebhookService');
|
|
78
|
+
initializeWebhookManager(tunnelService, webhookService);
|
|
79
|
+
// Start is async and non-blocking — failures are logged, not thrown
|
|
80
|
+
void getWebhookManager().start(port);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Webhook system is optional; polling continues to work
|
|
84
|
+
}
|
|
73
85
|
const url = `http://localhost:${port}`;
|
|
74
86
|
messages.success(`Server ready at ${fmt.code(url)}`);
|
|
75
87
|
messages.info('Press Ctrl+C to stop');
|
|
@@ -91,6 +103,9 @@ Examples:
|
|
|
91
103
|
// Force exit after 5s if graceful shutdown stalls
|
|
92
104
|
const forceExit = setTimeout(() => process.exit(0), 5000);
|
|
93
105
|
forceExit.unref();
|
|
106
|
+
if (hasWebhookManager()) {
|
|
107
|
+
await getWebhookManager().stop();
|
|
108
|
+
}
|
|
94
109
|
getPrSyncWatcher().stop();
|
|
95
110
|
getNotificationWatcher().stop();
|
|
96
111
|
await service.stop();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-webhook-status.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/load-webhook-status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sEAAsE,CAAC;AAEhH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAiBtE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { hasWebhookManager, getWebhookManager, } from '../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
|
|
3
|
+
export async function loadWebhookStatus() {
|
|
4
|
+
if (!hasWebhookManager()) {
|
|
5
|
+
return {
|
|
6
|
+
running: false,
|
|
7
|
+
tunnel: { connected: false, publicUrl: null },
|
|
8
|
+
webhooks: {
|
|
9
|
+
registered: [],
|
|
10
|
+
totalDeliveries: 0,
|
|
11
|
+
successCount: 0,
|
|
12
|
+
errorCount: 0,
|
|
13
|
+
ignoredCount: 0,
|
|
14
|
+
},
|
|
15
|
+
startedAt: null,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return getWebhookManager().getStatus();
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Delivery History: GET /api/webhooks/deliveries
|
|
3
|
+
*
|
|
4
|
+
* Returns recent webhook delivery records with optional filtering.
|
|
5
|
+
* Query params: ?status=success|error|ignored&eventType=pull_request&limit=50
|
|
6
|
+
*/
|
|
7
|
+
export declare const dynamic = "force-dynamic";
|
|
8
|
+
export declare function GET(request: Request): Promise<Response>;
|
|
9
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/webhooks/deliveries/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsB7D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Delivery History: GET /api/webhooks/deliveries
|
|
3
|
+
*
|
|
4
|
+
* Returns recent webhook delivery records with optional filtering.
|
|
5
|
+
* Query params: ?status=success|error|ignored&eventType=pull_request&limit=50
|
|
6
|
+
*/
|
|
7
|
+
import { hasWebhookManager, getWebhookManager, } from '../../../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
|
|
8
|
+
export const dynamic = 'force-dynamic';
|
|
9
|
+
export async function GET(request) {
|
|
10
|
+
if (!hasWebhookManager()) {
|
|
11
|
+
return Response.json({ deliveries: [] });
|
|
12
|
+
}
|
|
13
|
+
const url = new URL(request.url);
|
|
14
|
+
const statusFilter = url.searchParams.get('status');
|
|
15
|
+
const eventTypeFilter = url.searchParams.get('eventType');
|
|
16
|
+
const limitParam = url.searchParams.get('limit');
|
|
17
|
+
const limit = limitParam ? Math.min(parseInt(limitParam, 10) || 50, 200) : 50;
|
|
18
|
+
const manager = getWebhookManager();
|
|
19
|
+
let deliveries = [...manager.getDeliveryHistory()];
|
|
20
|
+
if (statusFilter) {
|
|
21
|
+
deliveries = deliveries.filter((d) => d.status === statusFilter);
|
|
22
|
+
}
|
|
23
|
+
if (eventTypeFilter) {
|
|
24
|
+
deliveries = deliveries.filter((d) => d.eventType === eventTypeFilter);
|
|
25
|
+
}
|
|
26
|
+
return Response.json({ deliveries: deliveries.slice(0, limit) });
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Webhook Receiver: POST /api/webhooks/github
|
|
3
|
+
*
|
|
4
|
+
* Receives webhook events from GitHub, validates the HMAC-SHA256 signature,
|
|
5
|
+
* and routes the event to the GitHubWebhookService for processing.
|
|
6
|
+
*
|
|
7
|
+
* This endpoint is exposed via a Cloudflare Tunnel so GitHub can reach it.
|
|
8
|
+
* Only POST requests are accepted; all other methods return 405.
|
|
9
|
+
*/
|
|
10
|
+
export declare const dynamic = "force-dynamic";
|
|
11
|
+
export declare function POST(request: Request): Promise<Response>;
|
|
12
|
+
/**
|
|
13
|
+
* Health check: GET /api/webhooks/github
|
|
14
|
+
* Returns whether the webhook system is active.
|
|
15
|
+
*/
|
|
16
|
+
export declare function GET(): Promise<Response>;
|
|
17
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/webhooks/github/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsD9D;AAED;;;GAGG;AACH,wBAAsB,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAS7C"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Webhook Receiver: POST /api/webhooks/github
|
|
3
|
+
*
|
|
4
|
+
* Receives webhook events from GitHub, validates the HMAC-SHA256 signature,
|
|
5
|
+
* and routes the event to the GitHubWebhookService for processing.
|
|
6
|
+
*
|
|
7
|
+
* This endpoint is exposed via a Cloudflare Tunnel so GitHub can reach it.
|
|
8
|
+
* Only POST requests are accepted; all other methods return 405.
|
|
9
|
+
*/
|
|
10
|
+
import { resolve } from '../../../../lib/server-container.js';
|
|
11
|
+
import { hasWebhookManager } from '../../../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
|
|
12
|
+
export const dynamic = 'force-dynamic';
|
|
13
|
+
export async function POST(request) {
|
|
14
|
+
// Verify webhook system is running
|
|
15
|
+
if (!hasWebhookManager()) {
|
|
16
|
+
return Response.json({ error: 'Webhook system not initialized' }, { status: 503 });
|
|
17
|
+
}
|
|
18
|
+
// Read raw body for signature validation
|
|
19
|
+
const rawBody = await request.text();
|
|
20
|
+
if (!rawBody) {
|
|
21
|
+
return Response.json({ error: 'Empty request body' }, { status: 400 });
|
|
22
|
+
}
|
|
23
|
+
// Get the webhook service from DI container
|
|
24
|
+
let webhookService;
|
|
25
|
+
try {
|
|
26
|
+
webhookService = resolve('IWebhookService');
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return Response.json({ error: 'Webhook service not available' }, { status: 503 });
|
|
30
|
+
}
|
|
31
|
+
// Validate GitHub signature
|
|
32
|
+
const signature = request.headers.get('x-hub-signature-256') ?? '';
|
|
33
|
+
const validation = webhookService.validateSignature(rawBody, signature, webhookService.getSecret());
|
|
34
|
+
if (!validation.valid) {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.warn(`[WebhookRoute] Invalid signature: ${validation.error}`);
|
|
37
|
+
return Response.json({ error: `Invalid signature: ${validation.error}` }, { status: 401 });
|
|
38
|
+
}
|
|
39
|
+
// Parse the event
|
|
40
|
+
const eventType = request.headers.get('x-github-event') ?? 'unknown';
|
|
41
|
+
const deliveryId = request.headers.get('x-github-delivery') ?? 'unknown';
|
|
42
|
+
let payload;
|
|
43
|
+
try {
|
|
44
|
+
payload = JSON.parse(rawBody);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return Response.json({ error: 'Invalid JSON payload' }, { status: 400 });
|
|
48
|
+
}
|
|
49
|
+
// Process the event asynchronously (respond immediately to GitHub)
|
|
50
|
+
void webhookService.handleEvent({
|
|
51
|
+
source: 'github',
|
|
52
|
+
eventType,
|
|
53
|
+
deliveryId,
|
|
54
|
+
payload,
|
|
55
|
+
});
|
|
56
|
+
return Response.json({ received: true, deliveryId });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Health check: GET /api/webhooks/github
|
|
60
|
+
* Returns whether the webhook system is active.
|
|
61
|
+
*/
|
|
62
|
+
export async function GET() {
|
|
63
|
+
const active = hasWebhookManager();
|
|
64
|
+
return Response.json({
|
|
65
|
+
active,
|
|
66
|
+
message: active
|
|
67
|
+
? 'Webhook receiver is active'
|
|
68
|
+
: 'Webhook system not initialized (cloudflared may not be installed)',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook System Status: GET /api/webhooks/status
|
|
3
|
+
*
|
|
4
|
+
* Returns the full webhook system status including tunnel state,
|
|
5
|
+
* registered webhooks, and delivery statistics.
|
|
6
|
+
*/
|
|
7
|
+
export declare const dynamic = "force-dynamic";
|
|
8
|
+
export declare function GET(): Promise<Response>;
|
|
9
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/webhooks/status/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAkB7C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook System Status: GET /api/webhooks/status
|
|
3
|
+
*
|
|
4
|
+
* Returns the full webhook system status including tunnel state,
|
|
5
|
+
* registered webhooks, and delivery statistics.
|
|
6
|
+
*/
|
|
7
|
+
import { hasWebhookManager, getWebhookManager, } from '../../../../../../../packages/core/src/infrastructure/services/webhook/webhook-manager.service.js';
|
|
8
|
+
export const dynamic = 'force-dynamic';
|
|
9
|
+
export async function GET() {
|
|
10
|
+
if (!hasWebhookManager()) {
|
|
11
|
+
return Response.json({
|
|
12
|
+
running: false,
|
|
13
|
+
tunnel: { connected: false, publicUrl: null },
|
|
14
|
+
webhooks: {
|
|
15
|
+
registered: [],
|
|
16
|
+
totalDeliveries: 0,
|
|
17
|
+
successCount: 0,
|
|
18
|
+
errorCount: 0,
|
|
19
|
+
ignoredCount: 0,
|
|
20
|
+
},
|
|
21
|
+
startedAt: null,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const manager = getWebhookManager();
|
|
25
|
+
return Response.json(manager.getStatus());
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/webhooks/page.tsx"],"names":[],"mappings":"AAGA,uEAAuE;AACvE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAA8B,YAAY,qDAQzC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { loadWebhookStatus } from '../actions/load-webhook-status.js';
|
|
3
|
+
import { WebhooksPageClient } from '../../components/features/webhooks/webhooks-page-client.js';
|
|
4
|
+
/** Skip static pre-rendering since we need runtime webhook manager. */
|
|
5
|
+
export const dynamic = 'force-dynamic';
|
|
6
|
+
export default async function WebhooksPage() {
|
|
7
|
+
const status = await loadWebhookStatus();
|
|
8
|
+
return (_jsx("div", { className: "flex h-full flex-col px-6 pb-6", children: _jsx(WebhooksPageClient, { initialStatus: status }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type WebhookDeliveryStatus = 'success' | 'ignored' | 'error';
|
|
2
|
+
export interface WebhookDeliveryRecord {
|
|
3
|
+
deliveryId: string;
|
|
4
|
+
eventType: string;
|
|
5
|
+
source: string;
|
|
6
|
+
receivedAt: string;
|
|
7
|
+
status: WebhookDeliveryStatus;
|
|
8
|
+
statusMessage: string;
|
|
9
|
+
durationMs: number;
|
|
10
|
+
payload: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export interface RegisteredWebhookInfo {
|
|
13
|
+
repoFullName: string;
|
|
14
|
+
webhookId: number;
|
|
15
|
+
repositoryPath: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WebhookSystemStatus {
|
|
18
|
+
running: boolean;
|
|
19
|
+
tunnel: {
|
|
20
|
+
connected: boolean;
|
|
21
|
+
publicUrl: string | null;
|
|
22
|
+
};
|
|
23
|
+
webhooks: {
|
|
24
|
+
registered: readonly RegisteredWebhookInfo[];
|
|
25
|
+
totalDeliveries: number;
|
|
26
|
+
successCount: number;
|
|
27
|
+
errorCount: number;
|
|
28
|
+
ignoredCount: number;
|
|
29
|
+
};
|
|
30
|
+
startedAt: string | null;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE;QACN,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,QAAQ,EAAE;QACR,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;QAC7C,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WebhookDeliveryRecord } from './types.js';
|
|
2
|
+
export interface WebhookDeliveryTableProps {
|
|
3
|
+
deliveries: WebhookDeliveryRecord[];
|
|
4
|
+
}
|
|
5
|
+
export declare function WebhookDeliveryTable({ deliveries }: WebhookDeliveryTableProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=webhook-delivery-table.d.ts.map
|
package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-delivery-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-delivery-table.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,qBAAqB,EAAyB,MAAM,SAAS,CAAC;AAE5E,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAcD,wBAAgB,oBAAoB,CAAC,EAAE,UAAU,EAAE,EAAE,yBAAyB,2CAsE7E"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { CheckCircle, XCircle, MinusCircle, ChevronDown, ChevronRight } from 'lucide-react';
|
|
5
|
+
import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card.js';
|
|
6
|
+
import { Badge } from '../../ui/badge.js';
|
|
7
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
|
|
8
|
+
import { cn } from '../../../lib/utils.js';
|
|
9
|
+
const STATUS_ICON = {
|
|
10
|
+
success: _jsx(CheckCircle, { className: "h-4 w-4 text-green-500" }),
|
|
11
|
+
error: _jsx(XCircle, { className: "h-4 w-4 text-red-500" }),
|
|
12
|
+
ignored: _jsx(MinusCircle, { className: "h-4 w-4 text-yellow-500" }),
|
|
13
|
+
};
|
|
14
|
+
const STATUS_LABEL = {
|
|
15
|
+
success: 'Success',
|
|
16
|
+
error: 'Error',
|
|
17
|
+
ignored: 'Ignored',
|
|
18
|
+
};
|
|
19
|
+
export function WebhookDeliveryTable({ deliveries }) {
|
|
20
|
+
const [statusFilter, setStatusFilter] = useState('all');
|
|
21
|
+
const [eventTypeFilter, setEventTypeFilter] = useState('all');
|
|
22
|
+
const [expandedId, setExpandedId] = useState(null);
|
|
23
|
+
const eventTypes = [...new Set(deliveries.map((d) => d.eventType))];
|
|
24
|
+
const filtered = deliveries.filter((d) => {
|
|
25
|
+
if (statusFilter !== 'all' && d.status !== statusFilter)
|
|
26
|
+
return false;
|
|
27
|
+
if (eventTypeFilter !== 'all' && d.eventType !== eventTypeFilter)
|
|
28
|
+
return false;
|
|
29
|
+
return true;
|
|
30
|
+
});
|
|
31
|
+
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(CardTitle, { className: "text-sm font-medium", children: ["Delivery History (", filtered.length, ")"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Select, { value: statusFilter, onValueChange: setStatusFilter, children: [_jsx(SelectTrigger, { className: "h-8 w-[120px]", children: _jsx(SelectValue, { placeholder: "Status" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All Status" }), _jsx(SelectItem, { value: "success", children: "Success" }), _jsx(SelectItem, { value: "error", children: "Error" }), _jsx(SelectItem, { value: "ignored", children: "Ignored" })] })] }), _jsxs(Select, { value: eventTypeFilter, onValueChange: setEventTypeFilter, children: [_jsx(SelectTrigger, { className: "h-8 w-[150px]", children: _jsx(SelectValue, { placeholder: "Event Type" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All Events" }), eventTypes.map((type) => (_jsx(SelectItem, { value: type, children: type }, type)))] })] })] })] }) }), _jsx(CardContent, { children: filtered.length === 0 ? (_jsx("p", { className: "text-muted-foreground py-8 text-center text-sm", children: "No delivery records yet. Webhook events will appear here when received." })) : (_jsx("div", { className: "space-y-1", children: filtered.map((delivery) => (_jsx(DeliveryRow, { delivery: delivery, expanded: expandedId === delivery.deliveryId, onToggle: () => setExpandedId(expandedId === delivery.deliveryId ? null : delivery.deliveryId) }, delivery.deliveryId))) })) })] }));
|
|
32
|
+
}
|
|
33
|
+
function DeliveryRow({ delivery, expanded, onToggle, }) {
|
|
34
|
+
const time = new Date(delivery.receivedAt);
|
|
35
|
+
const timeStr = time.toLocaleTimeString();
|
|
36
|
+
const dateStr = time.toLocaleDateString();
|
|
37
|
+
return (_jsxs("div", { className: cn('rounded-lg border', expanded && 'bg-muted/50'), children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-3 py-2 text-left text-sm", onClick: onToggle, children: [expanded ? (_jsx(ChevronDown, { className: "h-4 w-4 shrink-0" })) : (_jsx(ChevronRight, { className: "h-4 w-4 shrink-0" })), STATUS_ICON[delivery.status], _jsx(Badge, { variant: "outline", className: "text-xs", children: delivery.eventType }), _jsx("span", { className: "text-muted-foreground min-w-0 flex-1 truncate text-xs", children: delivery.deliveryId }), _jsxs("span", { className: "text-muted-foreground shrink-0 text-xs", children: [delivery.durationMs, "ms"] }), _jsx("span", { className: "text-muted-foreground shrink-0 text-xs", children: timeStr })] }), expanded ? (_jsxs("div", { className: "border-t px-3 py-3", children: [_jsxs("div", { className: "mb-2 grid grid-cols-2 gap-2 text-xs", children: [_jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Status:" }), ' ', _jsx(Badge, { variant: delivery.status === 'error' ? 'destructive' : 'secondary', className: "text-xs", children: STATUS_LABEL[delivery.status] })] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Date:" }), " ", dateStr, " ", timeStr] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Duration:" }), " ", delivery.durationMs, "ms"] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground", children: "Source:" }), " ", delivery.source] })] }), _jsxs("div", { className: "mb-2", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: "Message:" }), _jsx("p", { className: "text-sm", children: delivery.statusMessage })] }), _jsxs("div", { children: [_jsx("span", { className: "text-muted-foreground text-xs", children: "Payload:" }), _jsx("pre", { className: "bg-muted mt-1 max-h-60 overflow-auto rounded-md p-2 text-xs", children: JSON.stringify(delivery.payload, null, 2) })] })] })) : null] }));
|
|
38
|
+
}
|
package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { WebhookDeliveryTable } from './webhook-delivery-table.js';
|
|
3
|
+
declare const meta: Meta<typeof WebhookDeliveryTable>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const WithDeliveries: Story;
|
|
7
|
+
export declare const Empty: Story;
|
|
8
|
+
export declare const OnlyErrors: Story;
|
|
9
|
+
//# sourceMappingURL=webhook-delivery-table.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-delivery-table.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAwDhE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,oBAAoB,CAK3C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC"}
|
package/dist/src/presentation/web/components/features/webhooks/webhook-delivery-table.stories.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { WebhookDeliveryTable } from './webhook-delivery-table.js';
|
|
2
|
+
const mockDeliveries = [
|
|
3
|
+
{
|
|
4
|
+
deliveryId: 'abc-123-def',
|
|
5
|
+
eventType: 'pull_request',
|
|
6
|
+
source: 'github',
|
|
7
|
+
receivedAt: new Date(Date.now() - 60000).toISOString(),
|
|
8
|
+
status: 'success',
|
|
9
|
+
statusMessage: 'Processed successfully',
|
|
10
|
+
durationMs: 12,
|
|
11
|
+
payload: {
|
|
12
|
+
action: 'closed',
|
|
13
|
+
pull_request: {
|
|
14
|
+
number: 42,
|
|
15
|
+
merged: true,
|
|
16
|
+
html_url: 'https://github.com/acme/web-app/pull/42',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
deliveryId: 'abc-456-ghi',
|
|
22
|
+
eventType: 'check_suite',
|
|
23
|
+
source: 'github',
|
|
24
|
+
receivedAt: new Date(Date.now() - 120000).toISOString(),
|
|
25
|
+
status: 'success',
|
|
26
|
+
statusMessage: 'Processed successfully',
|
|
27
|
+
durationMs: 8,
|
|
28
|
+
payload: {
|
|
29
|
+
action: 'completed',
|
|
30
|
+
check_suite: { conclusion: 'success', head_branch: 'feat/login' },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
deliveryId: 'abc-789-jkl',
|
|
35
|
+
eventType: 'check_run',
|
|
36
|
+
source: 'github',
|
|
37
|
+
receivedAt: new Date(Date.now() - 180000).toISOString(),
|
|
38
|
+
status: 'error',
|
|
39
|
+
statusMessage: 'Feature not found for branch refs/heads/unknown',
|
|
40
|
+
durationMs: 3,
|
|
41
|
+
payload: { action: 'completed', check_run: { conclusion: 'failure' } },
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
deliveryId: 'abc-012-mno',
|
|
45
|
+
eventType: 'ping',
|
|
46
|
+
source: 'github',
|
|
47
|
+
receivedAt: new Date(Date.now() - 240000).toISOString(),
|
|
48
|
+
status: 'ignored',
|
|
49
|
+
statusMessage: 'Unhandled event type: ping',
|
|
50
|
+
durationMs: 0,
|
|
51
|
+
payload: { zen: 'Keep it logically awesome.' },
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
const meta = {
|
|
55
|
+
title: 'Features/Webhooks/WebhookDeliveryTable',
|
|
56
|
+
component: WebhookDeliveryTable,
|
|
57
|
+
parameters: { layout: 'padded' },
|
|
58
|
+
tags: ['autodocs'],
|
|
59
|
+
};
|
|
60
|
+
export default meta;
|
|
61
|
+
export const WithDeliveries = {
|
|
62
|
+
args: { deliveries: mockDeliveries },
|
|
63
|
+
};
|
|
64
|
+
export const Empty = {
|
|
65
|
+
args: { deliveries: [] },
|
|
66
|
+
};
|
|
67
|
+
export const OnlyErrors = {
|
|
68
|
+
args: { deliveries: mockDeliveries.filter((d) => d.status === 'error') },
|
|
69
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RegisteredWebhookInfo } from './types.js';
|
|
2
|
+
export interface WebhookRepoListProps {
|
|
3
|
+
webhooks: readonly RegisteredWebhookInfo[];
|
|
4
|
+
tunnelUrl: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function WebhookRepoList({ webhooks, tunnelUrl }: WebhookRepoListProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=webhook-repo-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-repo-list.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-repo-list.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,oBAAoB,2CA2D5E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { GitBranch, ExternalLink } from 'lucide-react';
|
|
4
|
+
import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card.js';
|
|
5
|
+
import { Badge } from '../../ui/badge.js';
|
|
6
|
+
export function WebhookRepoList({ webhooks, tunnelUrl }) {
|
|
7
|
+
if (webhooks.length === 0) {
|
|
8
|
+
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-sm font-medium", children: "Registered Repositories" }) }), _jsx(CardContent, { children: _jsx("p", { className: "text-muted-foreground text-sm", children: "No webhooks registered. Webhooks are automatically created for repositories with features in the Review lifecycle when cloudflared is available." }) })] }));
|
|
9
|
+
}
|
|
10
|
+
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs(CardTitle, { className: "text-sm font-medium", children: ["Registered Repositories (", webhooks.length, ")"] }) }), _jsx(CardContent, { children: _jsx("div", { className: "space-y-3", children: webhooks.map((webhook) => (_jsxs("div", { className: "flex items-center justify-between rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(GitBranch, { className: "text-muted-foreground h-4 w-4" }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: webhook.repoFullName }), _jsxs("p", { className: "text-muted-foreground text-xs", children: ["Webhook #", webhook.webhookId] })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "outline", className: "text-xs", children: "Active" }), tunnelUrl ? (_jsx("a", { href: `https://github.com/${webhook.repoFullName}/settings/hooks/${webhook.webhookId}`, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground", children: _jsx(ExternalLink, { className: "h-3.5 w-3.5" }) })) : null] })] }, webhook.webhookId))) }) })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { WebhookRepoList } from './webhook-repo-list.js';
|
|
3
|
+
declare const meta: Meta<typeof WebhookRepoList>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const WithWebhooks: Story;
|
|
7
|
+
export declare const Empty: Story;
|
|
8
|
+
export declare const SingleRepo: Story;
|
|
9
|
+
//# sourceMappingURL=webhook-repo-list.stories.d.ts.map
|
package/dist/src/presentation/web/components/features/webhooks/webhook-repo-list.stories.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-repo-list.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-repo-list.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAKtC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAK1B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { WebhookRepoList } from './webhook-repo-list.js';
|
|
2
|
+
const mockWebhooks = [
|
|
3
|
+
{ repoFullName: 'acme/web-app', webhookId: 12345, repositoryPath: '/home/user/web-app' },
|
|
4
|
+
{ repoFullName: 'acme/api-service', webhookId: 12346, repositoryPath: '/home/user/api-service' },
|
|
5
|
+
{ repoFullName: 'acme/shared-lib', webhookId: 12347, repositoryPath: '/home/user/shared-lib' },
|
|
6
|
+
];
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Features/Webhooks/WebhookRepoList',
|
|
9
|
+
component: WebhookRepoList,
|
|
10
|
+
parameters: { layout: 'padded' },
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
export const WithWebhooks = {
|
|
15
|
+
args: {
|
|
16
|
+
webhooks: mockWebhooks,
|
|
17
|
+
tunnelUrl: 'https://random-subdomain.trycloudflare.com',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export const Empty = {
|
|
21
|
+
args: {
|
|
22
|
+
webhooks: [],
|
|
23
|
+
tunnelUrl: null,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const SingleRepo = {
|
|
27
|
+
args: {
|
|
28
|
+
webhooks: [mockWebhooks[0]],
|
|
29
|
+
tunnelUrl: 'https://random-subdomain.trycloudflare.com',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WebhookSystemStatus } from './types.js';
|
|
2
|
+
export interface WebhookStatusCardsProps {
|
|
3
|
+
status: WebhookSystemStatus;
|
|
4
|
+
}
|
|
5
|
+
export declare function WebhookStatusCards({ status }: WebhookStatusCardsProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=webhook-status-cards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-status-cards.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-status-cards.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,uBAAuB,2CA2FrE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Activity, Globe, Webhook, CheckCircle, XCircle, MinusCircle } from 'lucide-react';
|
|
4
|
+
import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card.js';
|
|
5
|
+
import { Badge } from '../../ui/badge.js';
|
|
6
|
+
import { cn } from '../../../lib/utils.js';
|
|
7
|
+
export function WebhookStatusCards({ status }) {
|
|
8
|
+
const uptime = status.startedAt ? formatUptime(new Date(status.startedAt)) : null;
|
|
9
|
+
return (_jsxs("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "System Status" }), _jsx(Activity, { className: "text-muted-foreground h-4 w-4" })] }), _jsxs(CardContent, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: cn('h-2 w-2 rounded-full', status.running ? 'bg-green-500' : 'bg-red-500') }), _jsx("span", { className: "text-2xl font-bold", children: status.running ? 'Active' : 'Inactive' })] }), uptime ? (_jsxs("p", { className: "text-muted-foreground text-xs", children: ["Up for ", uptime] })) : (_jsx("p", { className: "text-muted-foreground text-xs", children: "Webhook system not started" }))] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Tunnel" }), _jsx(Globe, { className: "text-muted-foreground h-4 w-4" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx(Badge, { variant: status.tunnel.connected ? 'default' : 'destructive', children: status.tunnel.connected ? 'Connected' : 'Disconnected' }) }), status.tunnel.publicUrl ? (_jsx("p", { className: "text-muted-foreground mt-1 truncate text-xs", title: status.tunnel.publicUrl, children: status.tunnel.publicUrl })) : (_jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: "No tunnel URL" }))] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Webhooks" }), _jsx(Webhook, { className: "text-muted-foreground h-4 w-4" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: status.webhooks.registered.length }), _jsxs("p", { className: "text-muted-foreground text-xs", children: [status.webhooks.registered.length === 1 ? 'repository' : 'repositories', " registered"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Deliveries" }), _jsx(CheckCircle, { className: "text-muted-foreground h-4 w-4" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: status.webhooks.totalDeliveries }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(CheckCircle, { className: "h-3 w-3 text-green-500" }), status.webhooks.successCount] }), _jsxs("span", { className: "flex items-center gap-1", children: [_jsx(XCircle, { className: "h-3 w-3 text-red-500" }), status.webhooks.errorCount] }), _jsxs("span", { className: "flex items-center gap-1", children: [_jsx(MinusCircle, { className: "h-3 w-3 text-yellow-500" }), status.webhooks.ignoredCount] })] })] })] })] }));
|
|
10
|
+
}
|
|
11
|
+
function formatUptime(startedAt) {
|
|
12
|
+
const ms = Date.now() - startedAt.getTime();
|
|
13
|
+
const seconds = Math.floor(ms / 1000);
|
|
14
|
+
const minutes = Math.floor(seconds / 60);
|
|
15
|
+
const hours = Math.floor(minutes / 60);
|
|
16
|
+
if (hours > 0)
|
|
17
|
+
return `${hours}h ${minutes % 60}m`;
|
|
18
|
+
if (minutes > 0)
|
|
19
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
20
|
+
return `${seconds}s`;
|
|
21
|
+
}
|
package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { WebhookStatusCards } from './webhook-status-cards.js';
|
|
3
|
+
declare const meta: Meta<typeof WebhookStatusCards>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Active: Story;
|
|
7
|
+
export declare const Inactive: Story;
|
|
8
|
+
export declare const TunnelDisconnected: Story;
|
|
9
|
+
//# sourceMappingURL=webhook-status-cards.stories.d.ts.map
|
package/dist/src/presentation/web/components/features/webhooks/webhook-status-cards.stories.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-status-cards.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/webhooks/webhook-status-cards.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAuC5D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,kBAAkB,CAKzC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,MAAM,EAAE,KAEpB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAOhC,CAAC"}
|